1、简介
在做爬虫时,可以使用 XPath(XML Path Language) 进行网页信息提取。XPath 具有简单明了的路径选择表达式,以及诸多内建函数,可以用于字符串、数值、时间等类型匹配。
XPath 常用规则:
表达式 | 描述 |
nodename | 选取当前节点的所有子节点 |
/ | 选取当前节点的子节点 |
// | 选取当前节点的子孙节点 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取当前节点的属性 |
使用方法,如:
//title[@lang='eng']
表示,选择所有名称为 title,同时属性 lang 的值为 eng 的节点。
2、安装
XPath 的库为 lxml,安装方法如下:
pip install lxml
3、应用实例
通过 XPath 操作网页的简单实例如下:
(1)创建 xpath_sample.html 文件
<div>
<ul>
<li class="item-0"><a href="link1.html">Item-0</a>
<li class="item=1"><a href="link2.html">Item-1</a> </li>
<li class="item-inactive"><a href="link3.html">Item-2</a> </li>
<li class="item-3"><a href="link4.html">Item-3</a> </li>
<li class="item-4"><a href="link5.html">Item-4</a> </li>
</ul>
</div>
(2) xpath 使用代码:
from lxml import etree
html = etree.parse('xpath_sample.html', etree.HTMLParser())
result = etree.tostring(html)
print(result.decode('utf-8'))
(3)运行输出结果如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><div>
<ul>
<li class="item-0"><a href="link1.html">Item-0</a>
</li><li class="item=1"><a href="link2.html">Item-1</a> </li>
<li class="item-inactive"><a href="link3.html">Item-2</a> </li>
<li class="item-3"><a href="link4.html">Item-3</a> </li>
<li class="item-4"><a href="link5.html">Item-4</a> </li>
</ul>
</div></body></html>
xpath 处理后的内容,自动补全了网页内容,并添加了 html、body等必要标签。
4、提取所有节点
XPath 常用规则中 "//" 可以选取符合要求的所有节点,使用方法如下:
# ********************************************
# use of '//'
# ********************************************
from lxml import etree
html = etree.parse('xpath_sample.html', etree.HTMLParser())
results = html.xpath('//*')
for result in results:
print(result)
运行输出结果如下:
<Element html at 0x16c30ef9f08>
<Element body at 0x16c30f07048>
<Element div at 0x16c30f07088>
<Element ul at 0x16c30f070c8>
<Element li at 0x16c30f07108>
<Element a at 0x16c30f07188>
<Element li at 0x16c30f071c8>
<Element a at 0x16c30f07208>
<Element li at 0x16c30f07248>
<Element a at 0x16c30f07148>
<Element li at 0x16c30f07288>
<Element a at 0x16c30f072c8>
<Element li at 0x16c30f07308>
<Element a at 0x16c30f07348>
这里使用*代表匹配所有节点,也就是获取整个HTML文本中的所有节点。从运行结果可以看到,返回形式是一个列表,其中每个元素是Element类型,类型后面跟着节点的名称,如html、body、div,ul、li.a等,所有节点都包含在了列表中。
提取规则改为 "//a":
results = html.xpath('//a')
运行结果为:
<Element a at 0x252f6238088>
<Element a at 0x252f62380c8>
<Element a at 0x252f6238108>
<Element a at 0x252f6238148>
<Element a at 0x252f6238188>
5、提取子节点
XPath 常用规则中,"//"及"/" 可以选取子节点及子孙节点。若需要选取 li 节点的所有子节点 a,使用方法如下:
from lxml import etree
html = etree.parse('xpath_sample.html', etree.HTMLParser())
results = html.xpath('//li/a')
for result in results:
print(result)
运行输出结果如下:
<Element a at 0x249fc939fc8>
<Element a at 0x249fc946048>
<Element a at 0x249fc946088>
<Element a at 0x249fc9460c8>
<Element a at 0x249fc946108>
若需要选取 ul 节点的所有孙节点 a,使用方法如下:
from lxml import etree
html = etree.parse('xpath_sample.html', etree.HTMLParser())
results = html.xpath('//ul//a')
for result in results:
print(result)
运行输出结果如下:
<Element a at 0x2a0d8a69f48>
<Element a at 0x2a0d8a69f88>
<Element a at 0x2a0d8a69fc8>
<Element a at 0x2a0d8a77048>
<Element a at 0x2a0d8a77088>
后续公众号会发布系列教程,更多内容请关注公众号:程序猿学习日记