## **解析库-XPath的基本使用(2)**
导读:
上一章节我们讲述了Xpath的基本使用方法,常见的使用方式,最后讲到了文本的获取方式,这章将继续将Xpath的基本使用。
<br>
#### **1.属性的获取**
我们知道用text()可以获取节点内部文本,那么节点属性该怎样获取呢? 其实还是用@符号就可
以。例如,我们想获取所有li节点下所有a节点的href属性,代码如下:
~~~
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.tostring(etree.HTML(text)).decode("utf8") # 将其补全转为字符串,解码
html = etree.HTML(html) #构造XPath 解析对象
result = html.xpath('//li/a/@href')
print(result)
输出:
['link1.html', 'link2 . html', 'link3. html', 'link4. html', 'link5.html']
~~~
<br>
#### **2.属性多值匹配**
有时候,某些节点的某个属性可能有多个值,例如:
~~~
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)
输出结果:
[]
~~~
<br>
这时就需要用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)
输出结果:
['first item']
~~~
<br>
#### **3.多属性匹配**
另外,我们可能还遇到一种情况, 那就是根据多个属性确定一个节点, 这时就需要同时匹配多个
属性。此时可以使用运算符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)
输出结果:
['first item']
这里的and其实是XPath中的运算符。另外,还有很多运算符,如or、mod
~~~
<br>
#### **4.按序选择**
有时候,我们在选择的时候某些属性可能同时匹配了多个节点,但是只想要其中的某个节点,如
第二个节点或者最后一个节点,这时该怎么办呢?
~~~
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 = 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)
输出结果:
['first item']
['fifth item']
['first item', 'second item']
['third item']
~~~
<br>
#### **5.节点轴选择**
|名称|参数描述|
|:---- |:---|
| ancestor | 可以获取所有祖先节点
| attribute| 可以获取节点所有属性值
| child |可以获取所有直接子节点
|descendant|可以获取所有子孙节点
|following|可以获取当前节点之后的所有节点
|following-sibling|可以获取当前节点之后的所有同级节点
示例如下:
~~~
from lxml import etree
text = '''
<div>
<ul>
<li class="item-0"><a href="link1.html">first <a>sss</a>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 = 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::*')
print(result)
result = html.xpath('//li[1]/following::*[2]')
print(result)
result = html.xpath('//li[1]/following-sibling::*')
print(result)
输出如下:
[<Element html at 0x25e10bdb108>, <Element body at 0x25e10bdb0c8>, <Element div at 0x25e10bdb1c8>, <Element ul at 0x25e10bdb248>]
[<Element div at 0x25e10bdb1c8>]
['item-0']
[<Element a at 0x25e10bdb248>]
[<Element a at 0x25e10bdb248>, <Element a at 0x25e10bdb0c8>]
[<Element li at 0x25e10bdb1c8>, <Element a at 0x25e10bdb308>, <Element li at 0x25e10bdb2c8>, <Element a at 0x25e10bdb208>, <Element li at 0x25e10bdb288>, <Element a at 0x25e10bdb348>, <Element li at 0x25e10bdb388>, <Element a at 0x25e10bdb3c8>]
[<Element li at 0x25e10bdb1c8>, <Element li at 0x25e10bdb2c8>, <Element li at 0x25e10bdb288>, <Element li at 0x25e10bdb388>]
~~~
<br>
<span style="color:red">结语:</span>
到现在为止,我们基本上把可能用到的XPath选择器介绍完了。XPath功能非常强大,内置函数
非常多,熟练使用之后,可以大大提升HTML信息的提取效率。