利用python爬虫(part9)--Xpath与谓词の爱

网友投稿 281 2022-08-31


利用python爬虫(part9)--Xpath与谓词の爱

学习笔记 编辑器:Sublime 注意:这里的理论部分是关于XML文档的,但是介于HTML和XML的相似性,大家可以自行做类比,有的地方我也会用HTML和XML做类比。

上一篇:Xpath路径表达式

文章目录

​​谓词​​

​​谓词的格式与作用​​​​寻找特殊位置的节点​​​​寻找有特殊属性的节点​​​​寻找有特殊关系节点的节点​​​​使用谓词嵌套寻找节点​​

谓词

谓词是定位步中最吸引人的部分。真的很吸引人!!!

谓词的格式与作用

谓词的目的是给出定位步所寻找出的节点需满足的进一步条件,即当前节点在使用定位步的轴和节点测试找出若干个节点后,再使用谓词从这些节点中筛选出满足条件的节点。

谓词格式:

[条件表达式]

谓词中的条件表达式和节点有关,其值为ture或false,当条件表达式的值是true时,称节点满足谓词给出的条件,否则称节点不满足谓词给出的条件。

在谓词中,用or, and来表示逻辑关系,使用​​=, !=, <=, <, >=, >​​表示大小关系。

例如:

[position() >= 4 and position <= 6]

表示筛选出第4、5、6位置的节点.

如果比较的内容是数值类型,则既可以用关系符​​=, !=, <=, <, >=, >​​​,比较大小关系。如果比较的内容为字符串类型,则只能用关系符​​=, !=​​,比较两个字符串是否相同。

现给出一个简单的HTML文档(这个文档,之后也要用到),我们将这个文档命名为test11.html:

Xpath

  1. Huang 8 carrot
  2. Bai 10 celery
  3. Jack 20 cucumber
  4. Tim 30 straw

Bunny like to eat ....

对于上面的html文件,我们写一个Xpath表达式(定位步缩写形式):

/child::html/child::body/child::div[position()=2]/child::p/child::text()缩写:/html/body/div[2]/p/text()

第一个定位步为:

Document节点(即,根节点)

第二个定位步为:

child::html

由于HTML文档只有一个名为html的根标记,所以Document节点使用该定位步寻找出的节点集中只有一个名字是html的Element节点。

第三个定位步为:

child::body

Xpath在第2定位步后寻找出的节点使用第3定位步寻找出的节点集中只有一个名字是body的Element节点。

第四定位步为:

child::div[position()=2]

Xpath在第3定位步后寻找出的节点使用第4定位步寻找Element节点,则Xpath路径找出的节点集中只有1个名字是div的Element节点(对应着第2个div标记)。

第五定位步为:

child::p

Xpath在第4定位步后寻找出的节点使用第5定位步寻找出的节点集中只有一个名字是p的Element节点。

第六定位步:

child::text()

Xpath在第5定位步后寻找出的节点使用第6定位步寻找Text节点,则Xpath路径找出的节点集中有1个Text节点,这个Text节点名字是​​#text​​​,包含的文本内容为​​welcome to buy our product ....​​

寻找特殊位置的节点

在谓词中使用position()和last()函数可以寻找指定位置上的节点。

我觉得这里直接上例子会理解的比较快,所以,开始敲代码吧!

用我们刚才的test11.html文件为例,在python中进行匹配:

from lxml import etreewith open('test11.html', 'rb') as f: html = f.read().decode('utf-8')#print(html)parse_html = etree.HTML(html)my_xpath = '/html/body/ol/li[position() = 2]/name/text()'data_list = parse_html.xpath(my_xpath)print(data_list)print('-'*15)my_xpath = '/html/body/ol/li[last()]/name/text()'data_list = parse_html.xpath(my_xpath)print(data_list)print('-'*15)my_xpath = '/html/body/ol/li[last()-1]/name/text()'data_list = parse_html.xpath(my_xpath)print(data_list)print('-'*15)my_xpath = '/html/body/ol/li[position() >= 3 and position() <= 4]/name/text()'data_list = parse_html.xpath(my_xpath)print(data_list)

Sublime输出:

['Bai']---------------['Tim']---------------['Jack']---------------['Jack', 'Tim'][Finished in 0.6s]

Great!!!

寻找有特殊属性的节点

在谓语中使用​​attribute​​​轴或者​​@​​寻找具有特定属性或属性值的节点。

寻找具有指定属性和属性值的节点

如果要寻找具有指定属性的节点,可以在谓词中使用:

attribute::属性名1 逻辑关系符 attribute::属性名2 ... attribute::属性名n

如果要寻找具有指定属性和属性值的节点,可以在谓词中使用:

attribute::属性名1 大小关系符 '值' 逻辑关系符...attribute::属性名n 大小关系符 '值'

还是用我们刚才的test11.html文件为例,在python中进行匹配:

from lxml import etreewith open('test11.html', 'rb') as f: html = f.read().decode('utf-8')#print(html)parse_html = etree.HTML(html)my_xpath = '/html/body/ol/li[@class="Ra02"]/name/text()'data_list = parse_html.xpath(my_xpath)print(data_list)print('-'*15)my_xpath = '/html/body/div//*[@href]/@href'data_list = parse_html.xpath(my_xpath)print(data_list)print('-'*15)

Sublime输出:

['Jack']---------------[''in 0.4s]

使用contains()函数

如果希望寻找具有指定属性,并且属性值中包含有指定字符串的节点时,可以在谓词中使用contains()函数,格式为:

contains(attribute::属性名, '特定字符串')

再来个例子:

from lxml import etreewith open('test11.html', 'rb') as f: html = f.read().decode('utf-8')#print(html)parse_html = etree.HTML(html)my_xpath = '/html/body/ol/li[contains(@class, "Ra")]/name/text()'data_list = parse_html.xpath(my_xpath)print(data_list)

Sublime输出:

['Huang', 'Bai', 'Jack', 'Tim'][Finished in 0.4s]

寻找有特殊关系节点的节点

???为啥感觉读起来有点绕口

寻找有特殊关系节点的节点

如果要寻找有特殊关系节点的节点,但对该特殊关系节点所包含的内容没有特殊要求,可以在谓词中使用:

轴::节点名称1 逻辑关系符 轴::节点名称2 ... 轴::节点名称n

如果要寻找有特殊关系节点的节点,对该特殊关系节点所包含的内容有特殊要求,可以在谓词中使用:

轴::节点名称1 大小关系 '值' 逻辑关系符...轴::节点名称n 大小关系 '值'

再来个例子:

from lxml import etreewith open('test11.html', 'rb') as f: html = f.read().decode('utf-8')#print(html)parse_html = etree.HTML(html)my_xpath = '/html/body/*[descendant::p and descendant::a]/p/a/text()'data_list = parse_html.xpath(my_xpath)print(data_list)print('-'*15)my_xpath = '/html/body/ol/li[age=20]/name/text()'data_list = parse_html.xpath(my_xpath)print(data_list)print('-'*15)

Sublime输出:

['Anything', 'Perfact!']---------------['Jack']---------------[Finished in 0.6s]

使用contains()函数

如果要寻找有特殊关系节点的节点,且特殊关系节点包含的文本需要含有指定的字符串时,可以使用contains()函数,格式是:

contains(轴::节点名称, '特定字符串')

来个例子:

from lxml import etreewith open('test11.html', 'rb') as f: html = f.read().decode('utf-8')#print(html)parse_html = etree.HTML(html)my_xpath = '/html/body//li[contains(age, "0")]/name/text()'data_list = parse_html.xpath(my_xpath)print(data_list)print('-'*15)

Sublime输出:

['Bai', 'Jack', 'Tim']---------------[Finished in 0.6s]

使用谓词嵌套寻找节点

谓词的作用是给出节点需要满足的进一步条件,因此允许谓词继续使用谓词。

比如,对于嵌套谓词:

[div[descendant::a="Anything"]]

满足该谓词条件的节点必须有名字是div的子节点,且div节点中必须包含文本内容为"Anything"的a子孙节点。

如有错误,请求指出。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:利用python爬虫(part6)--用Xpath匹配带来的数据合并问题
下一篇:springboot整合minio实现文件上传与下载且支持链接永久访问
相关文章

 发表评论

暂时没有评论,来抢沙发吧~