使用XPath

Posted python-road

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用XPath相关的知识,希望对你有一定的参考价值。

Xpath全称XML Path Language,即XML路径语言,它是一门在XML文档中查找信息的语言,它最初是用来搜索XML文档的,但是它同样适用于html文档的搜索

一.XPth概览

XPth提供了非常简洁明了的路径选择表达式,还提供了超过100个内建函数,用于字符串,数值,时间的匹配以及节点,序列的处理等。

二.XPath常用规则

XPath常用规则

表 达 式 描 述
nodename 选取此节点的所有子节点
/ 从当前节点选取直接子节点
// 从当前节点选取子孙节点
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性

例如://title[@lang=‘eng‘],这就是一个XPath规则,它代表选择所有名称为title ,同时属性lang的值为eng的节点

三.实例引入

from lxml import etree
text=‘‘‘
<div>
<ul>
<li class="item-0"><a href="link1.html">first item</a></li>
<li class ="item-1"><a href="link2.html">second item</a></li>
<li class ="item-inactive"><a href="link3.html">third item</a></li>
<li class ="item-1"><a href="link4.html">fourth item</a></li>
<li class ="item-0"><a href="link5.html">fifth item</a>
</ul>
</div>
‘‘‘
html=etree.HTML(text)
result=etree.tostring(html)
print(result.decode(utf-8))

这里首先导入lxml库的etree模块,然后声明一段HTML文本,调用HTML类进行初始化,这样就成功构造了一个XPath解析对象,etree模块可以自动修正HTML文本,调用tostring()方法即可输出修正后的HTML代码,但是结果是bytes类型,所以利用decode()方法将其转化成str类型

from lxml import etree
html=etree.parse(Cookies.text,etree.HTMLParser())
result=etree.tostring(html)
print(result.decode(utf-8))

也可以直接读取文本文件进行解析。

四.所有节点

from lxml import etree
html=etree.parse("Cookies.text",etree.HTMLParser())
result=html.xpath("//*")
print(result)

这里使用*代表匹配所有节点,即整个HTML文本中的所有节点都会被获取

from lxml import etree
html=etree.parse("Cookies.text",etree.HTMLParser())
result=html.xpath("//li")
print(result)
print(result[0])

也可以匹配指定节点名称,提取的结果是一个列表形式,其中每个元素都是一个Element对象

五.子节点

通过/或//可以查找元素的子节点或子孙节点

from lxml import etree
html=etree.parse("Cookies.text",etree.HTMLParser())
result=html.xpath("//li/a")
print(result)

这里选取了所有li节点的所有直接a子节点

/用于选取直接子节点,//用于选取所有子孙节点

from lxml import etree
html=etree.parse("Cookies.text",etree.HTMLParser())
result=html.xpath("//ul//a")
print(result)

六.父节点

父节点用..来实现

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

这里首先选取href属性为link4.html的a节点,然后获取其父节点,然后在获取其class属性

也可以用parent::来获取父节点

from lxml import etree
html=etree.parse(Cookies.text,etree.HTMLParser())
result=html.xpath(//a[@href="link4.html"]/parent::*/@class)
print(result)

七.属性匹配

在选取时,可以用@符号进行属性过滤

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

八.文本获取

用XPath中的text()方法获取节点中的文本

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

这里并没有获取到任何文本,只获取到一个换行符,这是因为text()前面是/,而此处/的含义是选取直接子节点,而li的直接子节点都是a节点,文本都是在a节点内部,所以这里匹配到的结果就是被修正的li节点内部的换行符。

如果想要获取li节点内部的文本,有两种方式,一种是先选取a节点在获取文本,另一种是使用//。

先选取a节点再获取文本:

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

返回的两个结果刚好是节点文本。

使用//:

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

这里返回3个结果,前两个是节点文本,另外一个是最后一个li节点内部的文本,即换行符

九.属性获取

用@符号获取

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

十.属性多值匹配

这里html文本中li节点的class属性有两个值li和li-first。此时如果还想用之前的属性匹配获取,就无法匹配了

需要用contains()函数,代码如下

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

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

十一.多属性匹配

根据多个属性确定一个节点,这时就需要同时匹配多个属性

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

十二.按序选择

有时一个属性可能同时匹配了多个节点,这时可以根据顺序选取节点

from lxml import etree
html=etree.parse("Cookies.text",etree.HTMLParser())
result=html.xpath(//li[1]/a/text())
print(result)
result=html.xpath(//li[last()]/a/text())
print(result)
result=html.xpath(//li[position()<3]/a/text())
print(result)
result=html.xpath(//li[last()-2]/a/text())
print(result)

第一次选择时,选取了第一个li节点,中括号中传入数字1即可

第二次选择时,选取了最后一个节点li节点,中括号中传入last()即可,返回的便是最后一个li节点

第三次选择时,选取了位置小于3的li节点,也就是位置序号为1和2的节点

第四次选择时,选取了倒数第三个li节点,中括号中传入last()-2即可

十三.节点轴选择

XPath提供了很多节点轴选择方法,包括获取子元素,兄弟元素,父元素,祖先元素等

from lxml import etree
text=‘‘‘
<div>
<ul>
<li class="item-0"><a href="link1.html"><span>first item</span></a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-inactive"><a href="link3.html">third item</a></li>
<li class="item-1"><a href="link4.html">fourth item</a></li>
<li class="item-0"><a href="link5.html">fifth item</a>
</ul>
</div>
‘‘‘
html=etree.HTML(text)
result=html.xpath(//li[1]/ancestor::*)
print(result)
result=html.xpath(//li[1]/ancestor::div)
print(result)
result=html.xpath(//li[1]/attribute::*)
print(result)
result=html.xpath(//li[1]/child::a[@href="link1.html"])
print(result)
result=html.xpath(//li[1]/descendant::span)
print(result)
result=html.xpath(//li[1]/following::*[2])
print(result)
result=html.xpath(//li[1]/following-sibling::*)
print(result)

第一次选择时,调用了ancestor轴,可以获取所以祖先节点,直接使用*表示匹配所有节点,因此返回结果是第一个li节点的所有祖先节点

第二次选择时,加了限定条件div,得到的结果就只有div这个祖先节点

第三次选择时,调用了attribute轴,可以获取所有属性值,后面根据的选择器还是*,这代表获取节点的所有属性,返回的就是li节点的所有属性值

第四次选择时,调用了child轴,可以获取所有直接子节点

第五次选择时,调用了descendant轴,可以获取所有子孙节点。加了限定条件获取span节点,所以返回的结果只包含span节点不包括a节点

第六次选择时,调用了following轴,可以获取当前节点之后的所有节点,加了索引选择(第一个索引为1,为当前节点)

第七次选择时,调用了following-sibling轴,可以获取当前节点之后的所有同级节点,使用*匹配,获取了所有后续同级节点

 

以上是关于使用XPath的主要内容,如果未能解决你的问题,请参考以下文章

Xpath的使用

XML编程总结——使用XPath对象查询xml文档

selenium- Xpath的详细使用

Python爬虫 解析 xpath -- Xpath Helper插件的安装xpath的基本使用

xpath的使用

35XPath的使用示例