编程学习网 > 编程语言 > Python > Python使用lxml处理XML及网页抓取教程
2023
08-31

Python使用lxml处理XML及网页抓取教程

在本教程中,我们会学习lxml库和创建XML文档的基础知识,然后会处理XML和HTML文档。最后,我们将利用以上所学,融会贯通,看看如何使用lxml提取数据。本教程的每一步都配有实用的Python lxml示例。

阅读人群
本教程适用于对Python、XML和HTML有基本的了解的开发人员。简单地说,如果您知道XML中的属性是什么,那么就足以理解本文。
本教程使用Python3代码段,但所有内容都可以在Python2上运行,只需进行少量更改。
 
Python中的lxml是什么?
lxml是在Python中处理XML和HTML最快且功能丰富的库之一。该库本质上是C库libxml2和libxslt的封装。因此结合了C库的速度和Python的简单性。
使用Python lxml库,可以创建、解析和查询XML和HTML文档。它依赖于许多其他复杂的包,如Scrapy。

01#安装
下载和安装lxml库的最佳方法是去Python Package Index(PyPI):
https://pypi.org/project/lxml/
如果您使用的是Linux(基于debian),只需运行:
  sudo apt-get install python3-lxml
另一种方法是使用pip包管理器。这适用于Windows、Mac和Linux:
  pip3 install lxml
在Windows上,假设您正在运行Python3,只需使用pip install lxml。

02#创建一个简单的XML文档

任何XML或任何符合XML的HTML都可以看作一棵树。一棵树有根和树枝。树的每个分支可以具有更多分支。所有这些分支和根都分别表示一个Element。

一个非常简单的XML文档如下所示:


<root>
       <branch>
        <branch_one>
       </branch_one>
       <branch_one>
       </branch_one>
       <branch>
</root>

如果HTML是兼容XML的,它将遵循相同的概念。
请注意,HTML可能兼容也可能不兼容XML。例如,如果HTML的<br>没有相应的结束标记,它仍然是有效的HTML,但它不会是有效的XML。
在本教程的后半部分,我们将看看如何处理这些情况。接下来让我们专注于兼容XML的HTML。

03#元素类

使用python lxml创建XML文档,第一步是导入lxml的etree模块:
>>> from lxml import etree
每个XML文档都以根元素开始。可以使用元素类型创建。元素类型是一个灵活的容器对象,可以存储分层数据。可以描述为字典和列表之间的交叉。
在这个python lxml示例中,目标是创建一个兼容XML的HTML。这意味着根元素的名称将是html:
>>> root = etree.Element("html")
同样,每个html都会有一个头部和一个主体:
>>> head = etree.Element("head")
>>> body = etree.Element("body")

要创建父子关系,我们可以简单地使用append()方法。

>>> root.append(head)

>>> root.append(body)

在tostring()函数的帮助下,这个文档可以被序列化并输出到终端。此函数需要一个强制参数,即文档的根。我们可以选择将pretty_print设置为True以使输出更具可读性。
请注意,tostring()序列化程序会实际返回字节。这可以通过调用decode()转换为字符串:
>>> print(etree.tostring(root, pretty_print=True).decode())

04#子元素类

创建一个Element对象并调用append()函数会使代码变得混乱和不可读。最简单的方法是使用SubElement类型。它的构造函数有两个参数——父节点和元素名称。使用SubElement,以下两行代码可以替换为一行。
body = etree.Element("body")
root.append(body)
# is same as
body = etree.SubElement(root,"body")

05#设置文本和属性

使用lxml库设置文本非常容易。Element和SubElement的每个实例都公开了两个方法——text和set,前者用于指定文本,后者用于设置属性。以下是示例:
para = etree.SubElement(body, "p")
para.text="Hello World!"
同样,可以使用键值约定设置属性:
para.set("style", "font-size:20pt")

要注意的是,可以在SubElement的构造函数中传递该属性:
para = etree.SubElement(body, "p", style="font-size:20pt", id="firstPara")
para.text = "Hello World!"

这种方法的节省了代码行数,代码可读性也更强。这是完整的代码。将它保存在一个python文件中并运行它。它将输出一个HTML,它也是一个格式良好的XML。
from lxml import etree
root = etree.Element("html")
head = etree.SubElement(root, "head")
title = etree.SubElement(head, "title")
title.text = "This is Page Title"
body = etree.SubElement(root, "body")
heading = etree.SubElement(body, "h1", style="font-size:20pt", id="head")
heading.text = "Hello World!"

para = etree.SubElement(body, "p",  id="firstPara")

para.text = "This HTML is XML Compliant!"

para = etree.SubElement(body, "p",  id="secondPara")

para.text = "This is the second paragraph."
etree.dump(root)  # prints everything to console. Use for debug only

请注意,这里我们使用了etree.dump()而不是调用etree.tostring()。不同之处在于dump()只是将所有内容写入控制台而不返回任何内容,tostring()用于序列化并返回一个字符串,您可以将其存储在变量中或写入文件。dump()仅适用于调试,不应用于任何其他目的。

在代码段的底部添加以下几行并再次运行它:
with open(‘input.html’, ‘wb’) as f:
f.write(etree.tostring(root, pretty_print=True)

代码会将内容保存到您运行脚本的同一文件夹中的input.html。同样,这是一个格式良好的XML,可以看作XML或HTML。

如何在Python中使用LXML
解析XML文件?

上一节是关于创建XML文件的Python lxml教程。在本节中,我们将研究如何使用lxml库遍历和操作现有的XML文档。

在我们继续之前,将以下代码段保存为input.html。

<html>

  <head>

 <title>This is Page Title</title>

  </head>

  <body>

 <h1 style="font-size:20pt" id="head">Hello World!</h1>

 <p id="firstPara">This HTML is XML Compliant!</p>

 <p id="secondPara">This is the second paragraph.</p>

  </body>

</html>

解析XML文档时,结果是内存中的ElementTree对象。

原始XML内容可以在文件系统或字符串中。如果它在文件系统中,则可以使用parse方法加载它。请注意,parse方法将返回一个ElementTree类型的对象。要获取根元素,只需调用getroot()方法。

from lxml import etree

tree = etree.parse('input.html')

elem = tree.getroot()

etree.dump(elem) #prints file contents to console

lxml.etree模块公开了另一种可用于有效解析xml字符串中内容的方法—fromstring()

xml ='<html><body>Hello</body></html>'

root = etree.fromstring(xml)

etree.dump(root)

这里要注意的一个重要区别是fromstring()方法会返回一个元素对象。无需调用getroot()。

如果您想深入了解解析,复制以下内容到浏览器了解BeautifulSoup教程的详细内容:

https://oxylabs.io/blog/beautiful-soup-parsing-tutorial


这是一个用于解析HTML和XML文档的Python包。但是为了快速回答BeautifulSoup中的lxml是什么,lxml可以使用BeautifulSoup作为解析器后端。同样,BeautifulSoup可以使用lxml作为解析器。

在XML中查找元素

从广义上讲,有两种使用Python lxml库查找元素的方法。第一种是使用Python lxml查询语言:XPath和ElementPath。例如,以下代码将返回第一个段落元素。



请注意,选择器与XPath非常相似。另请注意,未使用根元素名称,因为elem包含XML树的根。

tree = etree.parse('input.html')

elem = tree.getroot()

para = elem.find('body/p')

etree.dump(para)

# Output

# <p id="firstPara">This HTML is XML Compliant!</p>

类似地,findall()将返回与选择器匹配的所有元素的列表。

elem = tree.getroot()

para = elem.findall('body/p')

for e in para:

 etree.dump(e)

# Outputs

# <p id="firstPara">This HTML is XML Compliant!</p>

# <p id="secondPara">This is the second paragraph.</p>

选择元素的第二种方法是直接使用XPath。熟悉XPath的开发人员更容易使用这种方法。此外,XPath可用于使用标准XPath语法返回元素的实例、文本或任何属性的值。

para = elem.xpath('//p/text()')

for e in para:

print(e)

# Output

# This HTML is XML Compliant!

# This is the second paragraph.

使用lxml.html处理HTML

在本文中,我们一直在使用兼容XML的格式良好的HTML。很多时候情况并非如此。对于这些场景,您可以简单地使用lxml.html而不是lxml.etree。



请注意,不支持直接从文件中读取。文件内容应首先以字符串形式读取。这是从同一HTML文件输出所有段落的代码。

from lxml import html

with open('input.html') as f:

html_string = f.read()

tree = html.fromstring(html_string)

para = tree.xpath('//p/text()')

for e in para:

print(e)

# Output

# This HTML is XML Compliant!

# This is the second paragraph

lxml网页抓取教程

现在我们知道如何解析和查找XML和HTML中的元素,唯一缺少的部分是获取网页的HTML。

为此,“requests”库是一个不错的选择。它可以使用pip包管理器安装:

pip install requests

一旦安装了requests库,就可以使用简单的get()方法检索任何网页的HTML。示例如下:

import requests

response = requests.get('http://books.toscrape.com/')

print(response.text)

# prints source HTML



可以与lxml结合以检索所需的任何数据。

这是一个输出维基百科国家列表的简单示例:

import requests

from lxml import html

response = requests.get('https://en.wikipedia.org/wiki/List_of_countries_by_population_in_2010')

tree = html.fromstring(response.text)

countries = tree.xpath('//span[@class="flagicon"]')

for country in countries:

    print(country.xpath('./following-sibling::a/text()')[0])



在这段代码中,response.text返回的HTML被解析为变量树。可以使用标准XPath语法进行查询,连接XPath。请注意,xpath()方法返回一个列表,因此在此代码片段中仅获取第一项。



这可以很容易地扩展为从HTML读取任何属性。例如,以下修改后的代码输出结果为国旗的国家名称和图像URL。

for country in countries:

flag = country.xpath('./img/@src')[0]

country = country.xpath('./following-sibling::a/text()')[0]

print(country, flag)

—— 结论 ——

在这个Python lxml教程中,介绍了使用lxml库处理XML和HTML。Python lxml库是一个轻量级、快速且功能丰富的库。可用于创建XML文档、读取现有文档和查找特定元素。这个库对于XML和HTML文档同样强大。结合Requests库,它也可以很容易地用于网页抓取。

以上就是Python使用lxml处理XML及网页抓取教程的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取