Python爬虫2.2 — xpath用法教程
综述
本系列文档用于对Python爬虫技术的学习进行简单的教程讲解,巩固自己技术知识的同时,万一一不小心又正好对你有用那就更好了。
Python 版本是3.7.4
前面的几篇文章对如何从网站上抓取网页数据进行了讲解,以及使用BeautifulSoup
进行页面数据提取,下面继续对如何解析抓取的页面进行解析分析得到我们想要的数据进行说明。本篇文章主要参考:菜鸟教程
XPath 介绍
什么是XPath
XPath (XML Path Language) 是一门在XML和HTML文档中查找信息的语言,可用来在XML和HTML文档中对元素和属性进行遍历。
XPath 路径表达式
XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。
XPath 标准函数
XPath 含有超过 100 个内建的函数。这些函数用于字符串值、数值、日期和时间比较、节点和 QName 处理、序列处理、逻辑值等等。
XPath 开发工具
- Chrome插件XPath Helper(推荐使用)。
- FireFox插件Try XPath。
XPath 语法
XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。
XML 实例文档
我们将在下面的例子中使用这个 XML 文档。
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book>
<title lang="eng">平凡的世界</title>
<author>路遥</author>
<price>40.8</price>
</book>
<book>
<title lang="zh_CN">蛙</title>
<author>莫言</author>
<price>23.6</price>
</book>
</bookstore>
选取节点
XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。 下面列出了最有用的路径表达式:
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
… | 选取当前节点的父节点。 |
@ | 选取属性。 |
具体样例:
路径表达式 | 结果 |
---|---|
bookstore | 选取 bookstore 元素的所有子节点。 |
/bookstore | 选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
//book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang | 选取名为 lang 的所有属性。 |
谓语
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
在下面的表格中,列出了带有谓语的一些路径表达式,以及表达式的结果:
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()❤️] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang=‘eng’] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
选取未知节点
XPath 通配符可用来选取未知的 XML 元素。
通配符 | 描述 |
---|---|
* | 匹配任何元素节点。 |
@* | 匹配任何属性节点。 |
node() | 匹配任何类型的节点。 |
在下面的表格中,列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
/bookstore/* | 选取 bookstore 元素的所有子元素。 |
//* | 选取文档中的所有元素。 |
//title[@*] | 选取所有带有属性的 title 元素。 |
选取若干路径
通过在路径表达式中使用"|"运算符,您可以选取若干个路径。
在下面的表格中,列出了一些路径表达式,以及这些表达式的结果:
路径表达式 | 结果 |
---|---|
//book/title | //book/price | 选取 book 元素的所有 title 和 price 元素。 |
//title | //price | 选取文档中的所有 title 和 price 元素。 |
/bookstore/book/title | //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
需要注意的
- /和//的区别:/代表之获取直接子节点。//获取所有子孙节点。一般//用的比较多,这个主要视情况而定。
- contains:有时候某个属性中包含了多个值,那么可以使用
contains
函数,示例代码如下:
//input[contains(@class,"s_i")]
- 谓词中的下标是从1开始的,不是从0开始的。
XPath 实例
- 属性定位
//input[@id='kw']
- 索引定位、层级定位
//div[@id='head']/div/div[2]/a[1]
//div[@id='head']//a[@class='toindex']
- 逻辑运算
//input[@class="s_ipt" and @name="wd"]
- 模糊匹配
contains
//input[contains(@class,"s_i")]
starts-with
//input[starts-with(@class,"s")]
- 取文本
//div[@id="head"]//a/text()
lxml 库
lmxl 是一个HTML/XML的解析器,主要的功能是如何解析和提取HTML\XML数据。
lxml是一个第三方Python库,使用前要先安装一下:
$ pip install lxml
使用lxml解析HTML代码
- 解析html字符串:使用
lxml.etree.HTML
进行解析,示例代码如下:
# 引入lxml库
from lxml import etree
html_element = etree.HTML(text)
print(etree.tostring(html_element, encoding='utf-8').decode())
- 解析html文件:使用
lxml.etree.parse
进行解析,示例代码如下:
# 引入lxml库
from lxml import etree
# 生成对象
html_element = etree.parse('xpath.html')
print(etree.tostring(html_element, encoding='utf-8').decode())
这个函数默认的是XML
解析器,所以如果碰到一些不规范的HTML
代码的时候就会解析错误,这时候就要自己创建HTML
解析器。示例代码如下:
# 引入lxml库
from lxml import etree
# 自定义解析器
parse = etree.HTMLParser(encoding='utf-8')
# 生成对象
html_element = etree.parse('xpath1.html', parse=parse)
print(etree.tostring(html_element, encoding='utf-8').decode())
在lxml中使用XPath语法
根据html是文件还是字符串判断进行分别使用
# 引入lxml库
from lxml import etree
# 生成对象
tree = etree.parse('xpath.html')
# ret = tree.xpath('//div[@class="tang"]/ul/li[1]/text()')
# ret = tree.xpath('//div[@class="tang"]/ul/li[last()]/a/@href')
ret = tree.xpath('//div[@class="tang"]/ul/li[@class="love" and @name="yang"]')
print(ret)
其他博文链接
- Python爬虫1.1 — urllib基础用法教程
- Python爬虫1.2 — urllib高级用法教程
- Python爬虫1.3 — requests基础用法教程
- Python爬虫1.4 — requests高级用法教程
- Python爬虫2.1 — BeautifulSoup用法教程
转载:https://blog.csdn.net/Zhihua_W/article/details/100688907