xpath应用以及列表推导式用法

xpath应用以及列表推导式用法

1.xpath

阿里真的太变态了,html里标签的idclassname动态变化!牛批!

xpath使用正则

image.png

至此,正则和xpath的完美结合结束,但是在xpath使用的过程中还有大大小小的坑。

例如该html使用xpath直接获取span/text()只有一个.,所以需要循环遍历里面的span标签

a = """
<div mxa="feedsb1:a" class="feedspN clearfix"><div style="width: 20%;" class="feedspO   feedspU   "><div mxa="feedsb1:b" class="feedspP">消耗(元) <i class="feeds_ feedspQ" mx-view="feeds/gallery/mx-popover/index?content=%E9%80%89%E5%AE%9A%E6%97%B6%E9%97%B4%E5%86%85%E7%9A%84%E4%BF%A1%E6%81%AF%E6%B5%81%E5%B9%BF%E5%91%8A%E6%80%BB%E8%8A%B1%E8%B4%B9%E3%80%82" id="mx_299"></i></div><div mxa="feedsb1:c" class="feedspR"><span class="xh-highlight"><span class="fontsize-20 font-tahoma bold">4,309</span>.<span class="fontsize-14 font-tahoma bold">72</span></span></div></div><div style="width: 20%;" class="feedspO  "><div mxa="feedsb1:b" class="feedspP">展现量 <i class="feeds_ feedspQ" mx-view="feeds/gallery/mx-popover/index?content=%E9%80%89%E5%AE%9A%E6%97%B6%E9%97%B4%E5%86%85%E7%9A%84%E4%BF%A1%E6%81%AF%E6%B5%81%E5%B9%BF%E5%91%8A%E5%B1%95%E7%8E%B0%E6%80%BB%E9%87%8F%E3%80%82" id="mx_300"></i></div><div mxa="feedsb1:c" class="feedspR"><span><span class="fontsize-20 font-tahoma bold">155,219</span></span></div></div><div style="width: 20%;" class="feedspO  "><div mxa="feedsb1:b" class="feedspP">点击量 <i class="feeds_ feedspQ" mx-view="feeds/gallery/mx-popover/index?content=%E9%80%89%E5%AE%9A%E6%97%B6%E9%97%B4%E5%86%85%E7%9A%84%E4%BF%A1%E6%81%AF%E6%B5%81%E5%B9%BF%E5%91%8A%E7%82%B9%E5%87%BB%E6%80%BB%E9%87%8F%E3%80%82" id="mx_301"></i></div><div mxa="feedsb1:c" class="feedspR"><span><span class="fontsize-20 font-tahoma bold">5,996</span></span></div></div><div style="width: 20%;" class="feedspO  "><div mxa="feedsb1:b" class="feedspP">千次展现成本(元) <i class="feeds_ feedspQ" mx-view="feeds/gallery/mx-popover/index?content=%E5%8D%83%E6%AC%A1%E5%B1%95%E7%8E%B0%E6%88%90%E6%9C%AC%20%3D%20%E6%B6%88%E8%80%97%20%2F%20%E5%B1%95%E7%8E%B0%E9%87%8F%20%2A%201000%E3%80%82" id="mx_302"></i></div><div mxa="feedsb1:c" class="feedspR"><span><span class="fontsize-20 font-tahoma bold">27</span>.<span class="fontsize-14 font-tahoma bold">77</span></span></div></div><div style="width: 20%;" class="feedspO  "><div mxa="feedsb1:b" class="feedspP" data-spm-anchor-id="a2et4.11816906.88888888.i3.56841f56QHkB09">点击成本(元) <i class="feeds_ feedspQ" mx-view="feeds/gallery/mx-popover/index?content=%E7%82%B9%E5%87%BB%E6%88%90%E6%9C%AC%20%3D%20%E6%B6%88%E8%80%97%20%2F%20%E7%82%B9%E5%87%BB%E9%87%8F%E3%80%82" id="mx_303"></i></div><div mxa="feedsb1:c" class="feedspR"><span><span class="fontsize-20 font-tahoma bold">0</span>.<span class="fontsize-14 font-tahoma bold">72</span></span></div></div></div>



from lxml import etree

s = etree.HTML(a)

a = [i.xpath("span/text()") for i in s.xpath("//div[starts-with(@class, 'feedsp')]/div[1]/div[2]/span")][0]
print(a)  #获取第二层span的text()

>>>
['4,309', '72']

循环xpath时,第二层循环不需要加/

Xpath使用正则匹配时,1.0版本无法使用ends-with 仅可以使用starts-with,所以使用下面方式匹配:

    js  ="""
            document.evaluate("//a[contains(@id,'adStrategyDkx')]", document).iterateNext().click()
            setTimeout('document.evaluate("//a[contains(@href,'exportOverProductCampaignReportList')]", document).iterateNext().click()',5000);
    """

    driver1.execute_script(js)

2.列表推导式

未使用推导式的代码

a =(['2,621', '35'],['210,852'],['2,398'],['12', '43'],['1', '09'])

for i in a:
    if len(i)==1:
        print(i[0].replace(',', ''))
    else:
        print(((i[0] + '.' + i[1]).replace(',', '')))


>>>
2621.35
210852
2398
12.43
1.09

使用列表推导式

a =(['2,621', '35'],['210,852'],['2,398'],['12', '43'],['1', '09'])

a = [i[0].replace(',', '') if len(i)==1 else ((i[0] + '.' + i[1]).replace(',', '')) for i in a ]

>>>
['2621.35', '210852', '2398', '12.43', '1.09']

使用列表推导式替换后重组

import re
a =[ ('636710425400', 318.09, 1, 5, '2021-04-08'), ('616873233546;\n617383035002;\n585098358905', 62.54, 1, 5, '2021-04-08'), ('39856905008', 120.5, 1, 5, '2021-04-08'), ('610474183283', 84.6, 1, 5, '2021-04-08'), ('625046034602;\n625333579394', 93.01, 1, 5, '2021-04-08'), ('608727393051;\n616119541298;\n610494565658;\n633320454564', 122.55, 1, 5, '2021-04-08')]
ccc =[(re.findall("(\d+);",str(i[0]))[0],i[1],i[2],i[3],i[4]) if ';' in str(i[0]) else i for i in a ]
for i in ccc:
    print(i)

>>>
('636710425400', 318.09, 1, 5, '2021-04-08')
('616873233546', 62.54, 1, 5, '2021-04-08')
('39856905008', 120.5, 1, 5, '2021-04-08')
('610474183283', 84.6, 1, 5, '2021-04-08')
('625046034602', 93.01, 1, 5, '2021-04-08')
('608727393051', 122.55, 1, 5, '2021-04-08')

总结:循环写最后,逻辑顺序排,第一放开头

3.xpath补充

获取直接子节点/
获取li标签下面的第一级的直接子节点,代码如下:

from lxml import etree
 
html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//li/a')
print(result)

注意:是直接子节点,二级以上不行

获取所有的子孙节点//

获取ul下面的所有a链接,包括孙子节点

from lxml import etree
 
html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//ul//a')
print(result)

获取父节点..

选中href属性为link4.html的a节点,然后再获取其父节点

from lxml import etree
 
html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//a[@href="link4.html"]/../@class')
print(result)

文本获取text()

from lxml import etree
 
html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//li[@class="item-0"]/a/text()')
print(result)

属性获取@

我们想获取所有li节点下所有a节点的href属性

from lxml import etree
 
html = etree.parse('./test.html', etree.HTMLParser())
result = html.xpath('//li/a/@href')
print(result)

属性多值匹配contains()

网页中常常会出现某个节点某个属性多个值

from lxml import etree
text = '''
<li class="li li-first"><a href="link.html">first item</a></li>
'''
html = etree.HTML(text)
result = html.xpath('//li[@class="li"]/a/text()')
print(result) 

如果是用上面的方式返回的是[],由于li的节点属性多个,li节点的class属性有两个值li和li-first,无法正确匹配
这时候就要使用contains()

from lxml import etree
text = '''
<li class="li li-first"><a href="link.html">first item</a></li>
'''
html = etree.HTML(text)
result = html.xpath('//li[contains(@class, "li")]/a/text()')
print(result)

这样通过contains()方法,第一个参数传入属性名称,第二个参数传入属性值,只要此属性包含所传入的属性值,就可以完成匹配了。

多属性匹配
我们可能还遇到一种情况,那就是根据多个属性确定一个节点,这时就需要同时匹配多个属性。此时可以使用运算符and来连接,示例如下:

from lxml import etree
text = '''
<li class="li li-first" name="item"><a href="link.html">first item</a></li>
'''
html = etree.HTML(text)
result = html.xpath('//li[contains(@class, "li") and @name="item"]/a/text()')
print(result)

xpath参考文档

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351