Python的lxml库学习

lxml是一个Python库,使用它可以轻松处理XML和HTML文件,还可以用于web爬取。市面上有很多现成的XML解析器,但是为了获得更好的结果,开发人员有时更愿意编写自己的XML和HTML解析器。这时lxml库就派上用场了。这个库的主要优点是易于使用,在解析大型文档时速度非常快,归档的也非常好,并且提供了简单的转换方法来将数据转换为Python数据类型,从而使文件操作更容易。

 

安装

通过国内镜像安装就可以,在电脑上打开命令窗口(win+R,然后输入cmd),用pip安装:

pip install lxml -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

这个命令是从豆瓣上获取资源并安装的,当然也可以直接安装:

pip install lxml

直接安装稍微慢一些吧。除非修改默认安装源(方法请自行搜索)。

现在,您已经在本地机器上安装了lxml库的副本。现在我们来动手实践一下,看看使用这个库可以做哪些很酷的事情。

 

功能

要在程序中使用lxml库,首先需要导入它。您可以使用以下命令:

001.jpg

这将从lxml库中导入我们感兴趣的etree模块。

 

创建HTML / XML文档

使用etree模块,我们可以创建XML/HTML元素及其子元素,这在我们试图写入或操作HTML或XML文件时非常有用。我们来尝试使用etree创建一个HTML文件的基本结构:

002.jpg

在上面的代码中,您需要知道Element函数至少需要一个参数,而SubElement函数至少需要两个参数。这是因为Element函数只“需要”将要创建的元素的名称,而SubElement函数不仅需要根节点的名称,还需要将要创建的子节点的名称。

同样重要的是,要知道这两个函数只对它们可以接受的参数数量有一个下界,而没有上界,因为您可以将任意多的属性与它们关联起来。要要向一个元素添加一个属性,只需向(Sub)Element函数添加一个附加参数,并以attributeName='attribute value'的形式指定属性。

我们试着运行上面所写的代码来获得关于这些函数更好的直观感觉:

001.jpg

输出:

002.jpg

还有一种方法可以以分层的方式创建和组织元素。我们也来探索一下:

003.jpg

因此,在本例中,每当我们创建一个新元素时,我们只需将它添加到根/父节点。

 

解析HTML / XML文档

到目前为止,我们只考虑到创建新元素,为它们分配属性,等等。现在我们来看一个例子,其中我们已经有一个HTML或XML文件,我们希望解析它来提取某些信息。假设我们有第一个示例中创建的HTML文件,我们来尝试获取一个特定元素的标记名称,然后打印所有元素的标记名称。

001.jpg

输出:

002.jpg

现在来遍历root节点中的所有子元素并打印它们的标签:

003.jpg

输出:

004.jpg

 

使用属性

现在我们来看看如何将属性关联到现有元素,以及如何检索给定元素的特定属性的值。

使用与之前相同的root元素,尝试以下代码:

001.jpg

输出:

002.jpg

在这里,我们可以看到newAttribute="attributeValue"确实添加到了根元素中。

现在我们来尝试获取在上面代码中设置的属性的值。这里我们使用root元素上的数组索引访问子元素,然后使用get()方法检索属性:

003.jpg

输出:

001.jpg

 

从元素中检索文本

现在我们已经看到了etree模块的基本功能,我们来尝试对HTML和XML文件做一些更有趣的事情。这些文件的标签之间差不多总是会有一些文本。那么,我们来看看如何向元素添加文本:

002.jpg

输出:

003.jpg

 

检查元素是否有子元素

接下来,我们应该能够检查两件非常重要的事情,因为在许多web爬取应用程序中都需要检查异常处理。我们要检查的第一件事是元素是否有子元素,第二件事是节点是否为一个Element。

我们对上面创建的节点进行以下操作:

001.jpg

上面的代码将输出“True”,因为根节点确实有子节点。但是,如果我们对根节点的子节点进行相同的检查,就像下面的代码中所示,输出将是“False”。

002.jpg

输出:

003.jpg

现在我们来做同样的事情看看每一个节点是否是一个Element:

004.jpg

输出:

005.jpg

iselement方法有助于确定您是否有一个有效的Element对象,从而确定您是否可以使用我们在这里展示的方法继续遍历它。

 

检查一个元素是否有父元素

刚才,我们展示了如何沿着层次结构向下走,即如何检查一个元素是否有子节点,现在在这一节中,我们将尝试沿着层次结构向上走,即如何检查并获取一个子节点的父节点。

001.jpg

第一行应该返回nothing(也就是None),因为根节点本身没有任何父节点。另外两个应该都指向根元素,即HTML标记。我们查看一下输出,看看结果是不是我们所期望的:

输出:

002.jpg

 

检索元素的同胞

在本节中,我们将学习如何在层次结构中横向遍历,它会检索树中元素的兄弟元素。

横向遍历树与垂直导航非常相似。对于后者,我们使用getparent和元素的长度,对于前者,我们将使用getnext和getprevious函数。让我们在之前创建的节点上尝试一下,看看它们是如何工作的:

003.jpg

输出:

004.jpg

在这里,您可以看到root[1].getnext()检索到了“body”标记,因为它是下一个元素,而root[1].getprevious()检索了“head”标记。

类似地,如果我们在根节点上使用getprevious函数,它将返回None,如果我们在root[2]上使用getnext函数,它也将返回None。

 

从字符串解析XML

我们继续学习,如果我们有一个XML或HTML文件,我们希望解析原始字符串以获取或操作所需的信息,我们可以通过下面的例子来实现:

001.jpg

输出:

如您所见,我们成功地更改了HTML文档中的一些文本。由于我们传递给tostring函数一个xml_declaration参数,所以还自动添加了XML doctype声明。

寻找元素

我们要讨论的最后一点在解析XML和HTML文件时非常方便。我们将检查一些方法,通过这些方法,我们可以查看一个Element是否具有任何特定类型的子元素,以及它是否包含一些子元素。

这有许多实际的用例,例如查找特定web页面上的所有链接元素。

001.jpg

输出:

002.jpg

 

发布了11 篇原创文章 · 获赞 9 · 访问量 673

猜你喜欢

转载自blog.csdn.net/yimuta9538/article/details/103829665