Python公开课 - 页面解析之XPath
前言
XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。
XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。
XPath最初是用来搜寻XML文档的,但是它同样适用于HTML文档的搜索。所以在做爬虫时,可以使用 XPath 来做相应的页面解析。
XPath常用规则
nodename
- 选取此节点的所有子节点/
- 从当前节点选取直接子节点//
- 从当前节点选取子孙节点.
- 选取当前节点..
- 选取当前节点的父节点@
选取属性
举个简单的例子进行说明:
//p[@lang=’english')
这就是一个 XPath 规则,它代表选择所有名称为p,且属性lang 的值为english的节点。
XPath节点
在 XPath 中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML 文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。
from lxml import etree
import lxml.html
text = '''
<html>
<body>
<div>
<ul>
<li class="item-0">
<a href="linkl.html">0 item</a>
</li>
<li class="item-1">
<a href="link2.html">2 item</a>
</li>
<li class="item-inactive item-1">
<a href="link3.html">3 item</a>
</li>
<li class="item-2">
<a href="link4.html">4 item</a>
</li>
<li class="item-3">
<a href="links5.html">5 item</a>
</li>
</ul>
</div>
</body>
</html>'''
html = lxml.html.fromstring(text)
result= etree.tostring(html)
print(result.decode('utf8'))
父节点 - Parent
在上面的例子中,ul节点是所有li的父节点,li是a的父节点
子节点 - Children
同理li是ul的子节点,a是li的子节点
同胞 - Sibling
所有的ul节点下的li节点都是同胞
先辈 - Ancestor
a的先辈包括li, ul, div等
子孙 - Descendant
所有节点都是html节点的子孙
查找
按属性查找
我们还可以用@符号进行属性过滤,比如如果要选取class为item-0 的li节点,可以这样实现:
result = html.xpath('//li[@class="item-0"]')
print(result)
输出:
[<Element li at 0x7f8431bc5548>]
包含关系属性查找
通过 contains()方法,第一个参数传人属性名称,第二个参数传人属性值,只要此属性包含所传入的属性值,就可以完成匹配了:
result = html.xpath('//li[contains(@class,"item-inactive")]/a/text()')
print(result)
输出:
['3 item']
多属性精确查找
and 其实是 XPath 中的运算符号,通过它可以实现多条件匹配:
result = html.xpath('//li[contains(@class,"item-inactive") and contains(@class,"item-1")]/a/text()')
print(result)
输出:
['3 item']
按顺序查找
这里我们使用了last()函数来选择最后一个,我们也可以有更多函数可以进行操作,参见XPath常用函数总结
result = html.xpath('//li[last()]/a/text()')
print(result)
输出:
['5 item']
节点轴查找
我们调用了 ancestor 轴,可以获取所有祖先节点。 其后需要跟两个冒号,然后是 节点的选择器,这里我们直接使用*,表示匹配所有节点,
result = html.xpath('//li[1]/ancestor::*')
print(result)
输出:
[<Element html at 0x7f48976dcef8>, <Element body at 0x7f48976f2548>, <Element div at 0x7f4897682c78>, <Element ul at 0x7f4897682d68>]
数据抽取
文本获取
用 XPath 中的 text()函数获取节点中的文本:
result = html.xpath('//li[@class="item-3"]/a/text()')
print(result)
输出:
['5 item']
属性获取
用@符号来获取属性值:
result = html.xpath('//li/a/@href')
print(result)
输出:
['linkl.html', 'link2.html', 'link3.html', 'link4.html', 'links5.html']
小结
本章基本上把可能用到的 XPath 选择器介绍完了。 XPath 功能非常强大,内置函数非常多, 熟练使用之后,可以非常方便的对页面进行内容提取。