Python爬虫利器三之Xpath语法与lxml库的用法

前言

前面咱们介绍了 BeautifulSoup 的用法,这个已是很是强大的库了,不过还有一些比较流行的解析库,例如 lxml,使用的是 Xpath 语法,一样是效率比较高的解析方法。若是你们对 BeautifulSoup 使用不太习惯的话,能够尝试下 Xpath。html

参考来源

lxml用法源自 lxml python 官方文档,更多内容请直接参阅官方文档,本文对其进行翻译与整理。node

lxmlpython

XPath语法参考 w3schoolgit

w3schoolgithub

安装

 pypi下载地址:https://pypi.python.org/pypi/lxml/3.4.2#downloadsapp

利用 pip 安装便可框架

XPath语法

XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历。XPath 是 W3C XSLT 标准的主要元素,而且 XQuery 和 XPointer 都构建于 XPath 表达之上。scrapy

节点关系

(1)父(Parent)学习

每一个元素以及属性都有一个父。测试

在下面的例子中,book 元素是 title、author、year 以及 price 元素的父:

(2)子(Children)

元素节点可有零个、一个或多个子。

在下面的例子中,title、author、year 以及 price 元素都是 book 元素的子:

(3)同胞(Sibling)

拥有相同的父的节点

在下面的例子中,title、author、year 以及 price 元素都是同胞:

(4)先辈(Ancestor)

某节点的父、父的父,等等。

在下面的例子中,title 元素的先辈是 book 元素和 bookstore 元素:

(5)后代(Descendant)

某个节点的子,子的子,等等。

在下面的例子中,bookstore 的后代是 book、title、author、year 以及 price 元素:

 

选取节点

XPath 使用路径表达式在 XML 文档中选取节点。节点是经过沿着路径或者 step 来选取的。

下面列出了最有用的路径表达式:

表达式 描述
nodename 选取此节点的全部子节点。
/ 从根节点选取。
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性。

实例

在下面的表格中,咱们已列出了一些路径表达式以及表达式的结果:

路径表达式 结果
bookstore 选取 bookstore 元素的全部子节点。
/bookstore 选取根元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终表明到某元素的绝对路径!
bookstore/book 选取属于 bookstore 的子元素的全部 book 元素。
//book 选取全部 book 子元素,而无论它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的全部 book 元素,而无论它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的全部属性。

谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点。

谓语被嵌在方括号中。

实例

在下面的表格中,咱们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式 结果
/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 属性。
/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 元素。

XPath 运算符

下面列出了可用在 XPath 表达式中的运算符:

运算符 描述 实例 返回值
| 计算两个节点集 //book | //cd 返回全部拥有 book 和 cd 元素的节点集
+ 加法 6 + 4 10
减法 6 – 4 2
* 乘法 6 * 4 24
div 除法 8 div 4 2
= 等于 price=9.80 若是 price 是 9.80,则返回 true。若是 price 是 9.90,则返回 false。
!= 不等于 price!=9.80 若是 price 是 9.90,则返回 true。若是 price 是 9.80,则返回 false。
< 小于 price<9.80 若是 price 是 9.00,则返回 true。若是 price 是 9.90,则返回 false。
<= 小于或等于 price<=9.80 若是 price 是 9.00,则返回 true。若是 price 是 9.90,则返回 false。
> 大于 price>9.80 若是 price 是 9.90,则返回 true。若是 price 是 9.80,则返回 false。
>= 大于或等于 price>=9.80 若是 price 是 9.90,则返回 true。若是 price 是 9.70,则返回 false。
or price=9.80 or price=9.70 若是 price 是 9.80,则返回 true。若是 price 是 9.50,则返回 false。
and price>9.00 and price<9.90 若是 price 是 9.80,则返回 true。若是 price 是 8.50,则返回 false。
mod 计算除法的余数 5 mod 2 1

lxml用法

初步使用

首先咱们利用它来解析 HTML 代码,先来一个小例子来感觉一下它的基本用法。

首先咱们使用 lxml 的 etree 库,而后利用 etree.HTML 初始化,而后咱们将其打印出来。

其中,这里体现了 lxml 的一个很是实用的功能就是自动修正 html 代码,你们应该注意到了,最后一个 li 标签,其实我把尾标签删掉了,是不闭合的。不过,lxml 由于继承了 libxml2 的特性,具备自动修正 HTML 代码的功能。

因此输出结果是这样的

不只补全了 li 标签,还添加了 body,html 标签。

文件读取

除了直接读取字符串,还支持从文件读取内容。好比咱们新建一个文件叫作 hello.html,内容为

利用 parse 方法来读取文件。

一样能够获得相同的结果。

XPath实例测试

依然以上一段程序为例

(1)获取全部的 <li> 标签

运行结果

可见,etree.parse 的类型是 ElementTree,经过调用 xpath 之后,获得了一个列表,包含了 5 个 <li> 元素,每一个元素都是 Element 类型

(2)获取 <li> 标签的全部 class

运行结果

(3)获取 <li> 标签下 href 为 link1.html 的 <a> 标签

运行结果

(4)获取 <li> 标签下的全部 <span> 标签

注意这么写是不对的

由于 / 是用来获取子元素的,而 <span> 并非 <li> 的子元素,因此,要用双斜杠

运行结果

(5)获取 <li> 标签下的全部 class,不包括 <li>

运行结果

(6)获取最后一个 <li> 的 <a> 的 href

运行结果

(7)获取倒数第二个元素的内容

运行结果

(8)获取 class 为 bold 的标签名

运行结果

经过以上实例的练习,相信你们对 XPath 的基本用法有了基本的了解。也能够利用 text 方法来获取元素的内容。

你们多加练习!

结语

XPath 是一个很是好用的解析方法,同时也做为爬虫学习的基础,在后面的 selenium 以及 scrapy 框架中都会涉及到这部分知识,但愿你们能够把它的语法掌握清楚,为后面的深刻研究作好铺垫。

转载:静觅 » Python爬虫利器三之Xpath语法与lxml库的用法

相关文章
相关标签/搜索