- 节点的基本类型
- Xpath路径表达式的基本语法
- 轴
- 轴的使用
- lxml的安装
- lxml的使用
你需要了解 XPath 路径表达式的基本语法,理解节点的基本类型,完成节点的获取、属性的匹配获取、多属性的匹配获取、文本的获取、按序选择等。
节点的基本类型
XPath 是一门在 XML 文档中查找信息的语言,虽然是被设计用来搜寻 XML 文档的,但是它也能应用于 HTML 文档,并且大部分浏览器也支持通过 XPath 来查询节点。在 Python 爬虫开发中,经常使用 XPath 查找提取网页中的信息,因此 XPath 非常重要。
在 XPath 中, XML 文档是被作为节点树来对待的,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。树的根被称为文档节点或者根节点。以下面的 XML 文档为例进行说明:
Harry Potter 29.99 Learning XML 39.95
- 根节点(Root Node)
根节点是一棵树的最顶层,根节点是唯一的。树上其它所有元素节点都是它的子节点或后代节点。对根节点的处理机制与其它节点相同。对树的匹配总是先从根节点开始。文档中的
- 元素节点(Element Nodes)
元素节点相对应的是文档中每个元素,一个元素节点的子节点可以为元素节点、注释节点、处理指令节点和文本节点。元素节点可以定义一个唯一的标识(id)。元素节点可以有拓展名,由两部分组成:命名空间 URL 和本地命名。文档中的
- 文本节点(Text Nodes)
文本节点包含一组字符数据,任何一个文本节点都没有相邻的兄弟文本节点,而且文本节点没有扩展名。文档中的Learning XML即为文本节点。
- 属性节点(Attribute Nodes)
每个元素节点有一个相关联的属性节点集合,元素是每个属性节点的父节点,但属性节点却不是其父元素的子节点。这就是说,通过查找元素的子节点可以匹配出元素的属性节点,但反过来不成立,只是单向的。再有,元素的属性节点没有共享性,也就是说不同的元素节点不共有同一个属性节点。文档中的lang="eng"即为属性节点。
- 命名空间节点(Namespace Nodes)
每个元素节点都有一个相关联的命名空间节点集。在 XML 文档中,命名空间是通过保留属性声明的。因此,在 XPath 中,该类节点与属性节点极为相似,它们与父元素之间的关系是单向的,并且不具有共享性。
- 处理指令节点(Processing Instruction Nodes)
处理指令节点对应于 XML 文档中的每一条处理指令。它也有扩展名,扩展名的本地命名指向处理对象,而命名空间部分为空。
- 注释节点(Comment Nodes)
注释节点对应于文档中的注释。
Xpath路径表达式的基本语法
XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是沿着路径(path)或者步(steps)来选取的。接下来介绍如何选取节点,首先了解一下常用的路径表达式,来进行节点的选取,如下表所示:
| 表达式 | 描述 |
|---|---|
| nodename | 选取此节点的所有子节点 |
| / | 从根节点选取 |
| // | 选择任意位置的某个节点 |
| . | 选取当前节点 |
| .. | 选取当前节点的父节点 |
| @ | 选取属性 |
根据路径表达式的规则,我们对上文的的 XML 文档进行节点选取,如下表所示。
| XPath路径表达式 | 含义 |
|---|---|
| bookstore | 选取 bookstore 元素的所有子节点 |
| /bookstore | 选取根元素 bookstore |
| /bookstore/book/text() | 选取属于 bookstore 子元素的 book 元素下的所有文本内容 |
| //book | 选取所有 book 子元素,而不管它们在文档中位置 |
| //@eng | 选取名为 eng 的所有属性 |
上面选取的例子最后实现的效果都是选取了所有符合条件的节点,是否能选取某个特定的节点或者包含某一个指定的值的节点呢?这就需要用到谓语,谓语被嵌在方括号中,谓语的用法如下表所示。
| XPath路径表达式 | 含义 |
|---|---|
| /bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素 |
| /bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素 |
| /bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素 |
| /bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素 |
| //title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素 |
| //title[@lang='eng'] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性 |
| //title[@lang='eng' and @] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性和值为good的class属性 |
| /bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00 |
| /bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00 |
XPath 在进行节点选取的时候可以使用通配符*匹配未知的元素,同时使用操作符|一次选取多条路径,使用示例如下表所示。
| XPath路径表达式 | 含义 |
|---|---|
| /bookstorechild::price | 选取当前节点的所有 price 孙节点 例如: 选取所有的price节点 |
你需要掌握:Python 环境下使用 XPath 对 HTML 文件进行解析。
lxml的安装
lxml 是 一个 HTML/XML 的解析器,主要的功能是解析和提取 HTML/XML 数据。lxml 和正则一样,也是用 C 实现的,是一款高性能的 Python HTML/XML 解析器,我们可以利用之前学习的 XPath 语法,来快速地定位特定元素以及节点信息。
如果本地 Python 环境没有安装 lxml,可以在命令提示符窗口输入命令pip install lxml,安装 lxml 模块,如下图所示。
lxml的使用
使用 lxml,需要先导入相关包,语法如下:
- from lxml import etree
现在有如下 HTML 代码,需要获取第一个 book 节点下的 title 节点中的 class 的属性值:
Harry Potter 29.99 Learning XML 39.95
使用 xpath 表达式解析网页之前,需要获取元素树对象,这里有两种方法:
- 如果上述代码为本地文件,并且文件名为test.html,获取元素树对象的代码如下所示:
- parse = etree.HTMLParser(encoding='utf-8') # 添加编码
- tree = etree.parse('test.html', parse) # 指定本地HTML文件读取
- 如果上述代码为字符串类型变量,并且变量名为html,获取元素树对象的代码如下所示:
- parse = etree.HTMLParser(encoding='utf-8') # 添加编码
- tree = etree.HTML(html, parse) # html为python字符串
获取元素树对象后,就可以使用 XPath 表达式解析网页了,代码如下所示:
- result = tree.xpath(xpath表达式) # 返回类型为列表
完成上述指定任务有多种实现方式,以下演示了四种不同的 XPath 表达式,都能够获取第一个 book 节点下的 title 节点中的 class 的属性值。
- # 相对路径 book 节点选择
- print(tree.xpath('//book[1]/title/@class')[0])
- # 相对路径 title 节点存在 class 属性条件选择
- print(tree.xpath('//title[@class]/@class')[0])
- # 同上, 但是使用了轴选择 class 属性值
- print(tree.xpath('//title[@class]/attribute::class')[0])
- # 绝对路径常规选择
- print(tree.xpath('/html/body/bookstore//book[1]/title/@class')[0])
以上代码都可以获取图中红框部分的内容。



