快速入门XPath语法,轻松解析爬虫时的HTML内容
HTML、XML、XPath简介
HTML是Hyper Text Markup Language(超文本标记语言)的缩写,我们在浏览器中看到的内容都是HTML代码经过浏览器渲染的结果。
XML是EXtensible Markup Language(可扩展标记语言)的缩写,XML是一种很类似HTML的标记语言,不过XML的设计宗旨是传输数据,而非显示数据。
XPath是XML Path Language(XML路径语言)的缩写,是一门在XML文档中查找信息的语言,用来提取XML文档中的元素和属性。
XPath语法介绍
路径表达式:
nodename 选取此节点的所有子节点。
/ 从根节点选取。正斜杠也是路径分隔符。
// 从任意位置选取文档中的节点。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取当前节点的属性
通配符:
* 任意元素。
@* 任意属性。
node() 任意子节点(元素,属性,内容)。
谓语:
//a[n] n为1开始的整数,选取排在第n个位置的<a>元素。
//a[last()] last()表示选取排在最后位置的<a>元素。
//a[last()-1] 和上面同理,表示选取倒数第二个<a>元素。
//a[position()<3] 选取第一个和第二个<a>元素。
//a[@href] 选取拥有href属性的<a>元素。
//a[@href='www.baidu.com'] 选取href属性值为'www.baidu.com'的<a>元素。
//a[@price>10] 选取price属性值大于10的<a>元素。
//a[@price>10]/span 选取price属性值大于10的<a>元素下的<span>元素。
选取多个路径:
//book/title | //book/price 选取<book>元素的所有<title>和<price>元素。
//title | //price 选取所有<title>和<price>元素。
/bookstore/book/title | //price 选取属于<bookstore>元素的<book>元素的所有<title>元素,以及所有的<price>元素。
运算符:
+ - * div 加减乘除。
= != 等于,不等于。
< <= 小于,小于等于。
> >= 大于,大于等于。
or and 或,与
mod 计算余数
常用函数:
contains(@属性,string) 选取属性里包含字符串string的元素。
text() 获取元素中的内容。
last() 选取最后一个元素。
position() 用于选取多个元素中某些位置(数字编号)的元素。
count() 返回元素的数量。
max() 返回最大的元素,min(),avg(),sum()同理。
lxml库使用
安装命令:
pip install lxml
实战演练:
# coding=utf-8
from lxml import etree
text = '''
<!DOCTYPE html>
<html>
<head>
<title>XPath Test(公众号:小斌哥ge)</title>
</head>
<body>
<div>
<ul>
<li id="1" class="item"><a href="link1.html">first item</a></li>
<li id="2" class="item"><a href="link2.html">second item</a></li>
<li id="3" class="item-inactive"><a href="link3.html">third item</a></li>
<li id="4" class="project"><a href="link4.html">first project</a></li>
<li id="5" class="project"><a href="link5.html">second project</a></li>
</ul>
</div>
</body>
</html>
'''
# 利用etree.HTML,将字符串解析为HTML文档
html = etree.HTML(text)
# 读取html文件
# html = etree.parse('test.html')
print(html)
# 按字符串序列化HTML文档
result = etree.tostring(html, pretty_print=True)
print(result)
<Element html at 0x1c3be4c9740>
b'<html>\n
<head>\n<title>XPath Test</title>\n</head>\n
<body>\n<div>\n
<ul>\n
<li id="1" class="item"><a href="link1.html">first item</a></li>\n
<li id="2" class="item"><a href="link2.html">second item</a></li>\n
<li id="3" class="item-inactive"><a href="link3.html">third item</a></li>\n
<li id="4" class="project"><a href="link4.html">first project</a></li>\n
<li id="5" class="project"><a href="link5.html">second project</a></li>\n
</ul>\n
</div>\n</body>\n
</html>\n'
用XPath从解析器中提取数据:
# 获取所有class属性值为'item'的<li>元素
infos = html.xpath("//li[@class='item']")
print(infos)
[<Element li at 0x25951272840>, <Element li at 0x25951272780>]
# 获取所有class属性中包含'pro'字符串的<li>元素
infos = html.xpath("//li[contains(@class, 'pro')]")
for info in infos:
# 获取<li>元素中<a>元素的文本内容
print(info.xpath("a/text()"))
['first project']
['second project']
# 获取倒数第二个<li>元素下的最后一个<a>元素
info = html.xpath("//li[last()-1]/a[last()]")
# 打印<a>元素的内容
print(info[0].text)
first project
# 获取前三个<li>元素下的<a>元素的内容
infos = html.xpath("//li[position()<4]/a/text()")
for info in infos:
# 打印<a>元素的文本内容
print(info)
first item
second item
third item
参考文档:
[1] XML W3School官方文档:http://www.w3school.com.cn/xml/index.asp
[2] XPath W3School官方文档:http://www.w3school.com.cn/xpath/index.asp
[3] lxml Python官方文档:http://lxml.de/index.html
评论