目录
上次说了Xpath的节点之间的关系和定位方式,这次根据上次的内容,来说下XPath的一些基本语法。
这些是常用的一些表达式。
表达式 | 含义 |
/ | 从根节点开始 |
// | 从当前节点开始 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 根据属性进行选择 |
* | 通配符表示任何元素节点 |
节点[索引] | 存在多个节点时,准确选择第几个 |
以下面代码为例来说下上面各表达式的具体使用方法。
<school>
<li class="people" id="01">
<p class="name">刘阿童木</p>
<p class="age">20</p>
<p class="gender">男</p>
</li>
<li class="people" id="02">
<p class="name">韩最厉害</p>
<p class="age">18</p>
<p class="gender">女</p>
</li>
</school>
备注:下面实际用到了lxml库,这里就不多介绍了,只理解xpath都定位到了那些元素即可,里面的data.xml就是上面的这个代码,然后xpath路径后的text()是为了可以获取到元素的内容。
1、"/" (从根节点开始)
一般看到"/"就是代表要获取xpath的绝对路径。
from lxml import etree #导入lxml库
data = etree.XML(open("data.xml", encoding="utf-8").read()) #获取data.xml的数据
#从根节点开始获取
test1 = data.xpath("/school/li/p/text()") #查看/school/li/p的获取到的节点都是那些
print(test1) #运行结果 ['刘阿童木', '20', '男', '韩最厉害', '18', '女']
#从非根节点开始获取
test2 = data.xpath("/li/p/text()") #从非根节点开始获取
print(test2) #运行结果[] (因为获取不到)
2、"//"(从任意节点开始)
一般情况下看到"//"代表的都是相对路径。
from lxml import etree #导入lxml库
data = etree.XML(open("data.xml", encoding="utf-8").read()) #获取data.xml的数据
#获取所有p节点的元素
test1 = data.xpath("//p/text()") #获取所有p节点的元素
print(test1) #运行结果:['刘阿童木', '20', '男', '韩最厉害', '18', '女']
3、"."(选取当前节点)
"."代表的选取当前节点的元素,一般情况下都是直接省略不写的。
from lxml import etree #导入lxml库
data = etree.XML(open("data.xml", encoding="utf-8").read()) #获取data.xml的数据
test1 = data.xpath("/school/li") #先定位到li元素下
test2 = test1[0].xpath(".//p/text()") #这时候加上.//定位的是当前目录,就是li目录下的所有的p元素(因为会定位到两个li元素,所以test1[0]取得就是第一个li元素)
print(test2) #打印结果 ['刘阿童木', '20', '男']
test3 = test1[0].xpath("//p/text()") #不加.直接//这样获取的就是所有的p元素。
print(test3) #打印结果 ['刘阿童木', '20', '男', '韩最厉害', '18', '女']
4、".."(选取当前节点的父节点)
".."代表的是选取当前节点的父节点,有时候使用相对路径定位到想要的元素的兄弟节点后,就可以使用".."选取到其共同的父节点,然后再重新进行定位。
from lxml import etree #导入lxml库
data = etree.XML(open("data.xml", encoding="utf-8").read()) #获取data.xml的数据
#先获取p节点,然后回到li节点,之后再定位到p节点
test1 = data.xpath("/school/li/p/../p/text()") #先获取p节点,然后回到li节点,之后再定位到p节点(主要看下".."的使用方法)
print(test1) #运行结果:['刘阿童木', '20', '男', '韩最厉害', '18', '女']
5、@(根据属性进行选择)
"@"表示根据属性选择,可以使用id、name、class等,使用规则为('//节点[@属性="xxx"]'),如果是文本属性的话规则为('//节点[text()="xxx"]'),一定要注意引号的用法,单引号里不能再有单引号了。
from lxml import etree #导入lxml库
data = etree.XML(open("data.xml", encoding="utf-8").read()) #获取data.xml的数据
test1 = data.xpath("//p[@class='name']/text()") #这个的意思是获取到p节点下所有的class=name的元素
print(test1) #打印结果为['刘阿童木', '韩最厉害']
test2 = data.xpath("//li[1]/p[@class='name']/text()") #准确定位,这时候先进入到第一个li下,然后再去获取p节点下class=name的元素
print(test1) #打印结果为:['刘阿童木']
6、*(代表匹配节点下的所有元素)
"*"代表的是匹配节点下的所有元素。
from lxml import etree #导入lxml库
data = etree.XML(open("data.xml", encoding="utf-8").read()) #获取data.xml的数据
test1 = data.xpath("//li/*/text()") #匹配li节点下的所有节点的元素
print(test1) #打印结果为:['刘阿童木', '20', '男', '韩最厉害', '18', '女']
7、节点[索引]
该方式一般用于有多个元素,这时候可以通过索引去决定使用第几个元素,这里的索引是从1开始的,需要匹配第几个填几就行。
from lxml import etree #导入lxml库
data = etree.XML(open("data.xml", encoding="utf-8").read()) #获取data.xml的数据
test1 = data.xpath("//li/p[3]/text()") #匹配li节点下的第三个p元素
print(test1) #打印结果为['男', '女']
test2 = data.xpath("//li[2]/p[3]/text()") #匹配第二个li节点下的第三个p的元素
print(test2) #打印结果为['女']
本章主要说明了XPath的一些基本的定位语法,这些基本是最常用的了,还有一些较为复杂的这些等到具体用的时候再详细说明吧。