Python 3网络爬虫实战
上QQ阅读APP看书,第一时间看更新

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基本语法表

XPath有以下几种节点关系:

  • 父(Parent)节点:每个元素以及属性都有一个父节点。
  • 子(Children)节点:元素节点可有零个、一个或多个子节点。
  • 同胞(Sibling)节点:拥有相同的父节点的节点。
  • 先辈(Ancestor)节点:某节点的父节点,父节点的父节点,等等。
  • 后代(Descendant)节点:某节点的子节点,子节点的子节点,等等。

下面通过一个简单的例子来说明XPath的使用。使用XPath读取文本,将其解析为一个XPath对象,并打印出来。

【示例3-31】解析字符串

以上代码首先导入lxml库,然后定义了一个长的跨行字符串,调用etree对象的HTML()方法将定义的字符串转化为一个XPath解析对象;接着调用etree对象的tostring()方法解析对象并输出代码;最后分别输出html的类型、result的类型以及经过转码后的内容。将以上代码保存为3-31.py,执行该代码的结果如图3-35所示。

图3-35 使用XPath解析字符串

查看图3-35的执行结果可以发现,html是属于类lxml.etree._Element的对象,result是属于类bytes的对象,最后输出的是转码后的内容。

提示

Bytes对象是由单个字节作为基本元素(8位,取值范围为0~255)组成的序列,为不可变对象。Bytes对象只负责以二进制字节序列的形式记录所需记录的对象,至于该对象到底表示什么(比如到底是什么字符),则由相应的编码格式解码所决定。

谓语用来查找某个特定的节点或者包含某个指定值的节点。谓语被嵌在方括号中。在表3-5中,我们列出了带有谓语的一些路径表达式,以及表达式的结果。

表3-5 谓词表

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

将以上代码保存为text.xml备用。

以上代码首先导入lxml模块中的etree,然后通过etree的parse()方法从一个XML文件解析一个对象,然后优化输出解析的内容。将以上代码保存为3-32.py,执行该代码,结果如图3-36所示。

图3-36 使用LXML解析XML文件

下面的示例将演示如何调用XPath方法来获取相应标签的文本内容。

【示例3-33】调用XPath获取标签内容

以上代码首先导入lxml模块中的etree,然后通过etree的parse()方法从一个XML文件解析一个对象,然后通过htmlEmt的xpath()方法获取结果文档中的所有li,并通过遍历将结果转换为字符串进行输出。将以上代码保存为3-33.py,执行该代码,结果如图3-37所示。

图3-37 使用XPath获取标签内容

除了获取指定标签外,还可以获取标签内部的文本内容,使用结果对象的text属性即可获取,类似于JavaScript中的innerHTML。下面的示例将演示获取所有超链接标签中的文本内容。

【示例3-34】获取标签中的文本

以上代码首先获取所有超链接,然后通过遍历输出结果,其中使用到结果对象的text属性以获取超链接标签中的文本。将代码保存为3-34.py,执行代码,结果如图3-38所示。

图3-38 获取标签中的文本