转载地址:https://blog.csdn.net/qq_42517220/article/details/88988910
什么是xpath?
- XPath (XML Path Language) 是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历。
- W3School官方文档:http://www.w3school.com.cn/xpath/index.asp
xpath开发工具
- 开源的XPath表达式编辑工具:XMLQuire(XML格式文件可用)
- Chrome插件 XPath Helper
- Firefox插件 XPath Checker
选取节点
XPath 使用路径表达式
来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似.
(1)下面列出了最常用的路径表达式
:
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
. | 选取当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性 |
XML文档示例
1 <?xml version="1.0" encoding="utf-8"?> 2 3 <bookstore> 4 5 <book category="cooking"> 6 <title lang="en">Everyday Italian</title> 7 <author>Giada De Laurentiis</author> 8 <year>2005</year> 9 <price>30.00</price> 10 </book> 11 12 </bookstore>
在下面的表格中,我们已列出了一些路径表达式以及表达式的结果
(2)谓语
(Predicates)
- 谓语用来查找某个特定的节点或者包含某个指定的值的节点,
被嵌在方括号中
。 - 在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果
(3)选取未知节点
- XPath 通配符可用来选取未知的 XML 元素
在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:
(4)选取若干路径
- 通过在路径表达式中使用
|
运算符,您可以选取若干个路径 - 在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果
(5)XPath的运算符
- 下面列出了可用在 XPath 表达式中的运算符
lxml库
(1)说明
- lxml 是 一个HTML/XML的解析器,主要的功能是如何解析和提取 HTML/XML 数据
- lxml和正则一样,也是用 C 实现的,是一款高性能的 Python HTML/XML 解析器
(2)安装
pip install lxml
(3)使用
我们利用它来解析 HTML 代码,简单示例:
1 # lxml_test.py 2 3 # 使用 lxml 的 etree 库 4 from lxml import etree 5 6 text = ''' 7 <div> 8 <ul> 9 <li class="item-0"><a href="link1.html">first item</a></li> 10 <li class="item-1"><a href="link2.html">second item</a></li> 11 <li class="item-inactive"><a href="link3.html">third item</a></li> 12 <li class="item-1"><a href="link4.html">fourth item</a></li> 13 <li class="item-0"><a href="link5.html">fifth item</a> # 注意,此处缺少一个 </li> 闭合标签 14 </ul> 15 </div> 16 ''' 17 18 #利用etree.HTML,将字符串解析为HTML文档 19 html = etree.HTML(text) 20 21 # 按字符串序列化HTML文档 22 result = etree.tostring(html) 23 24 print(result)
输出结果:
1 <html> 2 <body> 3 <div> 4 <ul> 5 <li class="item-0"><a href="link1.html">first item</a></li> 6 <li class="item-1"><a href="link2.html">second item</a></li> 7 <li class="item-inactive"><a href="link3.html">third item</a></li> 8 <li class="item-1"><a href="link4.html">fourth item</a></li> 9 <li class="item-0"><a href="link5.html">fifth item</a></li> 10 </ul> 11 </div> 12 </body> 13 </html>
lxml 可以自动修正 html 代码,例子里不仅补全了 li 标签,还添加了 body,html 标签
(4)文件读取
除了直接读取字符串,lxml还支持从文件里读取内容。我们新建一个hello.html文件:
1 <!-- hello.html --> 2 3 <div> 4 <ul> 5 <li class="item-0"><a href="link1.html">first item</a></li> 6 <li class="item-1"><a href="link2.html">second item</a></li> 7 <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li> 8 <li class="item-1"><a href="link4.html">fourth item</a></li> 9 <li class="item-0"><a href="link5.html">fifth item</a></li> 10 </ul> 11 </div>
再利用 etree.parse() 方法来读取文件
1 # lxml_parse.py 2 3 from lxml import etree 4 5 # 读取外部文件 hello.html 6 html = etree.parse('./hello.html') 7 result = etree.tostring(html, pretty_print=True) 8 9 print(result)
输出结果与之前相同
1 <html> 2 <body> 3 <div> 4 <ul> 5 <li class="item-0"><a href="link1.html">first item</a></li> 6 <li class="item-1"><a href="link2.html">second item</a></li> 7 <li class="item-inactive"><a href="link3.html">third item</a></li> 8 <li class="item-1"><a href="link4.html">fourth item</a></li> 9 <li class="item-0"><a href="link5.html">fifth item</a></li> 10 </ul> 11 </div> 12 </body> 13 </html>
XPath实例测试
1. 获取所有的 <li>
标签
1 # xpath_li.py 2 3 from lxml import etree 4 5 html = etree.parse('hello.html') 6 print type(html) # 显示etree.parse() 返回类型 7 8 result = html.xpath('//li') 9 10 print result # 打印<li>标签的元素集合 11 print len(result) 12 print type(result) 13 print type(result[0])
输出结果:
1 <type 'lxml.etree._ElementTree'> 2 [<Element li at 0x1014e0e18>, <Element li at 0x1014e0ef0>, <Element li at 0x1014e0f38>, <Element li at 0x1014e0f80>, <Element li at 0x1014e0fc8>] 3 5 4 <type 'list'> 5 <type 'lxml.etree._Element'>
2. 继续获取<li>
标签的所有 class
属性
1 # xpath_li.py 2 3 from lxml import etree 4 5 html = etree.parse('hello.html') 6 result = html.xpath('//li/@class') 7 8 print result
运行结果
1 ['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']
3. 继续获取<li>
标签下href 为 link1.html 的 <a>
标签
1 # xpath_li.py 2 3 from lxml import etree 4 5 html = etree.parse('hello.html') 6 result = html.xpath('//li/a[@href="link1.html"]') 7 8 print result
运行结果
1 [<Element a at 0x10ffaae18>]
4. 获取<li>
标签下的所有 <span>
标签
1 # xpath_li.py 2 3 from lxml import etree 4 5 html = etree.parse('hello.html') 6 7 # result = html.xpath('//li/span') 8 # 注意这么写是不对的: 9 # 因为 / 是用来获取子元素的,而 <span> 并不是 <li> 的子元素,所以,要用双斜杠 10 11 result = html.xpath('//li//span') 12 13 print result
运行结果
1 [<Element span at 0x10d698e18>]
5. 获取 <li>
标签下的<a>
标签里的所有 class
1 # xpath_li.py 2 3 from lxml import etree 4 5 html = etree.parse('hello.html') 6 result = html.xpath('//li/a//@class') 7 8 print result
运行结果
1 ['blod']
6. 获取最后一个 <li>
的 <a>
的 href
1 # xpath_li.py 2 3 from lxml import etree 4 5 html = etree.parse('hello.html') 6 7 result = html.xpath('//li[last()]/a/@href') 8 # 谓语 [last()] 可以找到最后一个元素 9 10 print result
运行结果
1 ['link5.html']
7. 获取倒数第二个元素的内容
1 # xpath_li.py 2 3 from lxml import etree 4 5 html = etree.parse('hello.html') 6 result = html.xpath('//li[last()-1]/a') 7 8 # text 方法可以获取元素内容 9 print result[0].text
运行结果
1 fourth item
8. 获取 class 值为 bold 的标签名
1 # xpath_li.py 2 3 from lxml import etree 4 5 html = etree.parse('hello.html') 6 7 result = html.xpath('//*[@class="bold"]') 8 9 # tag方法可以获取标签名 10 print result[0].tag
运行结果
1 span