![Python 3网络爬虫实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/139/36862139/b_36862139.jpg)
3.4 lxml模块解析数据
前面几节介绍了数据的存储,这一节来介绍数据的解析,这里将会使用到Python中的lxml模块。lxml是Python的一个解析库,支持HTML和XML的解析,支持XPath解析方式。本节重点来介绍如何使用lxml模块对获取到的数据进行解析。
3.4.1 安装模块
作为Python模块,在命令行执行pip命令进行安装即可。在“命令提示符”窗口执行以下命令:
pip3 install lxml
成功执行命令后,会自动联网下载相应模块并进行部署,之后就可以正常使用该模块了。
在Python中导入模块:
import lxml
执行代码,如果没有错误提示,就说明成功安装lxml模块。
3.4.2 XPath常用规则
lxml模块支持以XPath方式进行解析,本小节就简要介绍一下XPath的常用规则。在XPath中,有7种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档(根)节点。XML文档是被作为节点树来对待的。树的根被称为文档节点或者根节点。
XPath的常用规则如表3-4所示。
表3-4 XPath基本语法表
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-T92_8903.jpg?sign=1738811182-H3sQAcRQbMbeZ2PJ09lPp37XM6ZKNTCb-0-53c4a65d02cf45dd2ceb393fb2a72c68)
XPath有以下几种节点关系:
- 父(Parent)节点:每个元素以及属性都有一个父节点。
- 子(Children)节点:元素节点可有零个、一个或多个子节点。
- 同胞(Sibling)节点:拥有相同的父节点的节点。
- 先辈(Ancestor)节点:某节点的父节点,父节点的父节点,等等。
- 后代(Descendant)节点:某节点的子节点,子节点的子节点,等等。
下面通过一个简单的例子来说明XPath的使用。使用XPath读取文本,将其解析为一个XPath对象,并打印出来。
【示例3-31】解析字符串
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-P92_8906.jpg?sign=1738811182-hsFnc7SRwZog62We5FSVj1K2ctg7B5PQ-0-6f75bdf94663cfc5ac4593db949eaf5e)
以上代码首先导入lxml库,然后定义了一个长的跨行字符串,调用etree对象的HTML()方法将定义的字符串转化为一个XPath解析对象;接着调用etree对象的tostring()方法解析对象并输出代码;最后分别输出html的类型、result的类型以及经过转码后的内容。将以上代码保存为3-31.py,执行该代码的结果如图3-35所示。
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-P93_39321.jpg?sign=1738811182-iEbjz1rsm6HGxgPT3lTWyU0Fe1mPGXIo-0-4abeb07e41f8626bcbb3a67c87380265)
图3-35 使用XPath解析字符串
查看图3-35的执行结果可以发现,html是属于类lxml.etree._Element的对象,result是属于类bytes的对象,最后输出的是转码后的内容。
提示
Bytes对象是由单个字节作为基本元素(8位,取值范围为0~255)组成的序列,为不可变对象。Bytes对象只负责以二进制字节序列的形式记录所需记录的对象,至于该对象到底表示什么(比如到底是什么字符),则由相应的编码格式解码所决定。
谓语用来查找某个特定的节点或者包含某个指定值的节点。谓语被嵌在方括号中。在表3-5中,我们列出了带有谓语的一些路径表达式,以及表达式的结果。
表3-5 谓词表
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-T93_9099.jpg?sign=1738811182-SkcQ2sPcbX2BPrzQVlHXwR0kDcgo7VCe-0-13c9943540aba3f654b963d89fbec05a)
XPath通配符可用来选取未知的XML元素。
选取bookstore元素的所有子元素:
/bookstore/*
选取文档中的所有元素:
//*
选取所有带有属性的title元素。
//title[@*]
通过在路径表达式中使用“|”运算符,可以选取若干个路径。
选取book元素的所有title和price元素:
//book/title //book/price
选取文档中的所有title和price元素:
//title //price
选取属于bookstore元素的book元素的所有title元素,以及文档中所有的price元素。
/bookstore/book/title //price
转换XML:
Import lxml # 首先要先导入库 etree.HTML() # 这个就是转换为XML的Python的语法,HTML括号内填入目标站点的源码
注意
在运用到Python抓取时要先转换为XML。
3.4.3 读取文件进行解析
LXML除了可以解析HTML字符串外,还可以解析HTML文件。下面的示例将说明如何使用LXML解析HTML文件。
【示例3-32】调用parse方法来读取文件的文件名:text.xml
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-P94_9247.jpg?sign=1738811182-iMiCAmgQ5wTjAC65ke3a2ciJQMIUyKSP-0-3256e23ad91ab98581d55ff12ca9ba94)
将以上代码保存为text.xml备用。
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-P95_9333.jpg?sign=1738811182-VywBmgR9kDXuEAgkYBzFjNMGdQLkLedf-0-364b7dda6d1e60be4a7b9f83161d6843)
以上代码首先导入lxml模块中的etree,然后通过etree的parse()方法从一个XML文件解析一个对象,然后优化输出解析的内容。将以上代码保存为3-32.py,执行该代码,结果如图3-36所示。
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-P95_39322.jpg?sign=1738811182-Woi9qx72CWGBjaieBzonnFplLhuBczRX-0-dd7bec6e15dfc852363a2ef398a6816e)
图3-36 使用LXML解析XML文件
下面的示例将演示如何调用XPath方法来获取相应标签的文本内容。
【示例3-33】调用XPath获取标签内容
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-P95_9334.jpg?sign=1738811182-d5oMOAVEm7i8PHFLrEBh20uUAoVIRKql-0-461ed3f607f1d9f23c08202ec7deb510)
以上代码首先导入lxml模块中的etree,然后通过etree的parse()方法从一个XML文件解析一个对象,然后通过htmlEmt的xpath()方法获取结果文档中的所有li,并通过遍历将结果转换为字符串进行输出。将以上代码保存为3-33.py,执行该代码,结果如图3-37所示。
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-P95_39323.jpg?sign=1738811182-hJaIPa9EumD9LS6jGgsu0gmoANNpfPSJ-0-32e85a802fc4a334b63939b0034a4617)
图3-37 使用XPath获取标签内容
除了获取指定标签外,还可以获取标签内部的文本内容,使用结果对象的text属性即可获取,类似于JavaScript中的innerHTML。下面的示例将演示获取所有超链接标签中的文本内容。
【示例3-34】获取标签中的文本
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-P96_9378.jpg?sign=1738811182-JHcIreQcoMAzTtZJ5iiVWxF1j45iUE6J-0-d33f9790cd311b5899e74272a95b99ba)
以上代码首先获取所有超链接,然后通过遍历输出结果,其中使用到结果对象的text属性以获取超链接标签中的文本。将代码保存为3-34.py,执行代码,结果如图3-38所示。
![](https://epubservercos.yuewen.com/60895D/19549639601513806/epubprivate/OEBPS/Images/Figure-P96_39324.jpg?sign=1738811182-hsnMzP1TKMUeCA8L4ygZteRux4mbacTq-0-13f99d2627faaace3ad5b17ba7697a9b)
图3-38 获取标签中的文本