如何在Python中解析XML指南

学习如何使用ElementTree、lxml和SAX等库在Python中解析XML,以增强您的数据处理项目。
1 min read
如何在Python中解析XML

可扩展标记语言(XML)是一种广泛使用的格式,用于存储和交换结构化数据。XML文件通常用于表示层次结构数据,例如配置文件、数据交换格式、Web服务响应和网站地图。

在Python中解析XML文件是一项常见任务,特别是用于自动化处理从Web API或网络抓取中获取的数据的手动过程。

在本文中,您将学习一些用于在Python中解析XML的库,包括ElementTree模块lxml库minidom简单API for XML(SAX)untangle

XML文件的关键概念

在学习如何在Python中解析XML之前,您必须了解什么是XML模式定义(XSD)以及XML文件的组成元素。了解这些内容可以帮助您选择适合的Python库来完成解析任务。

XSD是定义XML文档中允许的结构、内容和数据类型的模式规范。它用作根据预定义规则验证XML文件结构和内容的语法。

一个XML文件通常包括命名空间根元素属性元素文本内容等元素,它们共同表示结构化数据。

  • 命名空间 允许在XML文档中唯一标识元素和属性。 命名空间 有助于避免命名冲突并实现XML文档之间的互操作性。
  • 根元素 是XML文档中的顶级元素。它作为导航XML结构的起点,并包含所有其他元素作为其子元素。
  • 属性 提供有关元素的附加信息。它们在元素的开始标签中指定,并由名称-值对组成。
  • 元素 是XML文档的构建块,表示所描述的数据或结构。元素可以嵌套在其他元素中,以创建层次结构。
  • 文本内容 是指元素的开始和结束标签内包含的文本数据。它可以包括纯文本、数字或其他字符。

例如,Bright Data网站地图具有以下XML结构:

  • urlset根元素
  • <urlset xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd>urlset元素的命名空间声明,表示此声明的规则扩展到urlset元素。其下的所有元素必须符合此命名空间定义的模式。
  • url根元素的第一个子元素。
  • locurl元素的子元素。

现在,您对XSD和XML文件元素有了一些了解,让我们利用这些信息,使用几个库来解析XML文件。

在Python中解析XML的各种方法

为了演示,您将使用Bright Data网站地图,该地图以XML格式提供。在以下示例中,使用Python requests库获取Bright Data网站地图内容。

Python requests库不是内置的,因此在继续之前需要安装它。您可以使用以下命令安装:

pip install requests

ElementTree

ElementTree XML API提供了一个简单直观的API,用于在Python中解析和创建XML数据。它是Python标准库中的一个内置模块,这意味着您无需显式安装任何东西。

例如,您可以使用findall()方法从根元素中找到所有url元素,并打印loc元素的文本值,如下所示:

import xml.etree.ElementTree as ET
import requests

url = 'https://brightdata.com/post-sitemap.xml'

response = requests.get(url)
if response.status_code == 200:

    root = ET.fromstring(response.content)

    for url_element in root.findall('.//{http://www.sitemaps.org/schemas/sitemap/0.9}url'):
        loc_element = url_element.find('{http://www.sitemaps.org/schemas/sitemap/0.9}loc')
        if loc_element is not None:
            print(loc_element.text)
else:
    print("Failed to retrieve XML file from the URL.")

网站地图中的所有URL都会在输出中打印出来:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/addressing-brand-protection-from-every-angle
https://brightdata.com/case-studies/taking-control-of-the-digital-shelf-with-public-online-data
https://brightdata.com/case-studies/the-seo-transformation
https://brightdata.com/case-studies/data-driven-automated-e-commerce-tools
https://brightdata.com/case-studies/highly-targeted-influencer-marketing
https://brightdata.com/case-studies/data-driven-products-for-smarter-shopping-solutions
https://brightdata.com/case-studies/workplace-diversity-facilitated-by-online-data
https://brightdata.com/case-studies/alternative-travel-solutions-enabled-by-online-data-railofy
https://brightdata.com/case-studies/data-intensive-analytical-solutions
https://brightdata.com/case-studies/canopy-advantage-solutions
https://brightdata.com/case-studies/seamless-digital-automations

ElementTree是一个用户友好的方式,用于在Python中解析XML数据,具有简洁的API,使得导航和操作XML结构变得容易。然而,ElementTree也有其局限性,它缺乏对模式验证的强大支持,如果您需要在解析前确保严格遵守模式规范,它并不是理想的选择。

如果您有一个读取RSS源的小脚本,ElementTree的用户友好API将是提取每个源项的标题、描述和链接的有用工具。然而,如果您的用例涉及复杂的验证或大型文件,最好考虑使用其他库如lxml。

lxml

lxml是 一个快速、易用且功能丰富的API,用于在Python中解析XML文件;但它不是Python中的预构建库。虽然一些Linux和Mac平台已经安装了lxml包,其他平台则需要手动安装。

lxml通过PyPI分发,您可以使用以下pip命令安装lxml

pip install lxml

安装后,您可以使用lxml的各种API方法,如find()findall()findtext()get()get_element_by_id()来解析XML文件。

例如,您可以使用findall()方法遍历url元素,找到它们的loc元素(即url元素的子元素),然后使用以下代码打印位置文本:

from lxml import etree
import requests

url = "https://brightdata.com/post-sitemap.xml"

response = requests.get(url)
if response.status_code == 200:

    root = etree.fromstring(response.content)


    for url in root.findall(".//{http://www.sitemaps.org/schemas/sitemap/0.9}url"):
        loc = url.find("{http://www.sitemaps.org/schemas/sitemap/0.9}loc").text.strip()
        print(loc)
else:
    print("Failed to retrieve XML file from the URL.")

输出显示了网站地图中找到的所有URL:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/addressing-brand-protection-from-every-angle
https://brightdata.com/case-studies/taking-control-of-the-digital-shelf-with-public-online-data
https://brightdata.com/case-studies/the-seo-transformation
https://brightdata.com/case-studies/data-driven-automated-e-commerce-tools
https://brightdata.com/case-studies/highly-targeted-influencer-marketing
https://brightdata.com/case-studies/data-driven-products-for-smarter-shopping-solutions
https://brightdata.com/case-studies/workplace-diversity-facilitated-by-online-data
https://brightdata.com/case-studies/alternative-travel-solutions-enabled-by-online-data-railofy
https://brightdata.com/case-studies/data-intensive-analytical-solutions
https://brightdata.com/case-studies/canopy-advantage-solutions
https://brightdata.com/case-studies/seamless-digital-automations

到目前为止,您已经学会了如何查找元素并打印它们的值。现在,让我们在解析XML之前探讨模式验证。这一过程确保文件符合模式定义的结构。

网站地图的XSD看起来是这样的:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.sitemaps.org/schemas/sitemap/0.9"
           xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
           elementFormDefault="qualified"
           xmlns:xhtml="http://www.w3.org/1999/xhtml">


  <xs:element name="urlset">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="url" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="url">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="loc" type="xs:anyURI"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

要使用模式验证网站地图,请手动复制它并创建一个名为schema.xsd的文件。

使用此XSD验证XML文件,请使用以下代码:

from lxml import etree

import requests

url = "https://brightdata.com/post-sitemap.xml"

response = requests.get(url)

if response.status_code == 200:

    root = etree.fromstring(response.content)

    try:
        print("Schema Validation:")
        schema_doc = etree.parse("schema.xsd")
        schema = etree.XMLSchema(schema_doc)
        schema.assertValid(root)
        print("XML is valid according to the schema.")
    except etree.DocumentInvalid as e:
        print("XML validation error:", e)

在这里,您使用etree.parse()方法解析XSD文件。然后,使用解析的XSD文档内容创建一个XML模式。最后,使用assertValid()方法根据XML模式验证XML根文档。如果模式验证通过,您的输出包括一条类似于XML根据模式验证通过的消息。否则,将引发DocumentInvalid异常。

您的输出应如下所示:

Schema Validation:
   XML is valid according to the schema.

现在,让我们读取一个使用xpath方法查找元素的XML文件。

要使用xpath()方法读取元素,请使用以下代码:

from lxml import etree

import requests

url = "https://brightdata.com/post-sitemap.xml"
response = requests.get(url)

if response.status_code == 200:

    root = etree.fromstring(response.content)

    print("XPath Support:")
    root = etree.fromstring(response.content)

    namespaces = {"ns": "http://www.sitemaps.org/schemas/sitemap/0.9"}
    for url in root.xpath(".//ns:url/ns:loc", namespaces=namespaces):
        print(url.text.strip())

在这段代码中,您注册了命名空间前缀ns并将其映射到命名空间URIhttp://www.sitemaps.org/schemas/sitemap/0.9。在XPath表达式中,您使用ns前缀指定命名空间中的元素。最后,表达式.//ns:url/ns:loc选择命名空间中url元素的所有loc元素。

您的输出将如下所示:

XPath Support:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/addressing-brand-protection-from-every-angle
https://brightdata.com/case-studies/taking-control-of-the-digital-shelf-with-public-online-data
https://brightdata.com/case-studies/the-seo-transformation
https://brightdata.com/case-studies/data-driven-automated-e-commerce-tools
https://brightdata.com/case-studies/highly-targeted-influencer-marketing
https://brightdata.com/case-studies/data-driven-products-for-smarter-shopping-solutions
https://brightdata.com/case-studies/workplace-diversity-facilitated-by-online-data
https://brightdata.com/case-studies/alternative-travel-solutions-enabled-by-online-data-railofy
https://brightdata.com/case-studies/data-intensive-analytical-solutions
https://brightdata.com/case-studies/canopy-advantage-solutions
https://brightdata.com/case-studies/seamless-digital-automations

如您所见,find()findall()方法比xpath方法更快,因为xpath会将所有结果收集到内存中,然后再返回。除非有特定原因使用XPath查询,否则建议使用find()方法。

lxml提供了强大的功能,用于解析和操作XML和HTML。它支持使用XPath表达式进行复杂查询,验证文档与模式匹配,甚至允许进行可扩展样式表语言转换(XSLT)。这使其在性能和高级功能至关重要的场景中非常理想。然而,请记住,lxml需要单独安装,因为它不是核心Python包的一部分。

如果您处理的大型或复杂的XML数据需要高性能和高级操作功能,应考虑使用lxml。例如,如果您正在处理金融数据源的XML格式,可能需要使用XPath表达式提取特定元素(如股票价格),验证数据与金融模式的准确性,并可能使用XSLT转换数据以进行进一步分析。

minidom

minidom是一个轻量级和简单的XML解析库,包含在Python的标准库中。虽然它不像lxml那样功能丰富或高效,但它提供了一种直接的方法,在Python中解析和操作XML数据。

您可以使用DOM对象中可用的各种方法来访问元素。例如,您可以使用getElementsByTagName()方法通过标签名称检索元素的值。

以下示例演示如何使用minidom库解析XML文件并通过标签名称获取元素:

import requests
import xml.dom.minidom

url = "https://brightdata.com/post-sitemap.xml"

response = requests.get(url)
if response.status_code == 200:
    dom = xml.dom.minidom.parseString(response.content)

    urlset = dom.getElementsByTagName("urlset")[0]
    for url in urlset.getElementsByTagName("url"):
        loc = url.getElementsByTagName("loc")[0].firstChild.nodeValue.strip()
        print(loc)
else:
    print("Failed to retrieve XML file from the URL.")

您的输出如下所示:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/addressing-brand-protection-from-every-angle
https://brightdata.com/case-studies/taking-control-of-the-digital-shelf-with-public-online-data
https://brightdata.com/case-studies/the-seo-transformation
https://brightdata.com/case-studies/data-driven-automated-e-commerce-tools
https://brightdata.com/case-studies/highly-targeted-influencer-marketing
https://brightdata.com/case-studies/data-driven-products-for-smarter-shopping-solutions
https://brightdata.com/case-studies/workplace-diversity-facilitated-by-online-data
https://brightdata.com/case-studies/alternative-travel-solutions-enabled-by-online-data-railofy
https://brightdata.com/case-studies/data-intensive-analytical-solutions
https://brightdata.com/case-studies/canopy-advantage-solutions
https://brightdata.com/case-studies/seamless-digital-automations

minidom通过将XML数据表示为DOM树来工作。这个树结构使得导航和操作数据变得容易,非常适合用于读取、修改或构建简单XML结构的基本任务。

如果您的程序涉及从XML文件读取默认设置,minidom的DOM方法允许您轻松访问XML文件中的特定设置,例如找到子节点或属性。使用minidom,您可以轻松地从XML文件中检索特定设置(如font-size节点),并在您的应用程序中使用其值。

SAX解析器

SAX解析器是Python中一种事件驱动的XML解析方法,它按顺序处理XML文档并在遇到文档的不同部分时生成事件。与构建表示整个XML文档的树结构的DOM解析器不同,SAX解析器不构建完整的文档表示,而是在解析过程中发出开始标签、结束标签和文本内容等事件。

SAX解析器非常适合处理大规模XML文件或流,因为它们在不将整个文档加载到内存中的情况下增量地操作XML数据,从而提高内存效率。

使用SAX解析器时,您需要定义响应特定XML事件的事件处理程序,例如解析器发出的startElementendElement事件。这些事件处理程序可以根据XML文档的结构和内容执行自定义操作。

以下示例演示如何使用SAX解析器解析XML文件,通过定义startElementendElement事件并从网站地图文件中检索URL信息:

import requests
import xml.sax.handler
from io import BytesIO

class MyContentHandler(xml.sax.handler.ContentHandler):
    def __init__(self):
        self.in_url = False
        self.in_loc = False
        self.url = ""

    def startElement(self, name, attrs):
        if name == "url":
            self.in_url = True
        elif name == "loc" and self.in_url:
            self.in_loc = True

    def characters(self, content):
        if self.in_loc:
            self.url += content

    def endElement(self, name):
        if name == "url":
            print(self.url.strip())
            self.url = ""
            self.in_url = False
        elif name == "loc":
            self.in_loc = False

url = "https://brightdata.com/post-sitemap.xml"

response = requests.get(url)
if response.status_code == 200:

    xml_content = BytesIO(response.content)

    content_handler = MyContentHandler()
    parser = xml.sax.make_parser()
    parser.setContentHandler(content_handler)
    parser.parse(xml_content)
else:
    print("Failed to retrieve XML file from the URL.")

您的输出如下所示:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/addressing-brand-protection-from-every-angle
https://brightdata.com/case-studies/taking-control-of-the-digital-shelf-with-public-online-data
https://brightdata.com/case-studies/the-seo-transformation
https://brightdata.com/case-studies/data-driven-automated-e-commerce-tools
https://brightdata.com/case-studies/highly-targeted-influencer-marketing
https://brightdata.com/case-studies/data-driven-products-for-smarter-shopping-solutions
https://brightdata.com/case-studies/workplace-diversity-facilitated-by-online-data
https://brightdata.com/case-studies/alternative-travel-solutions-enabled-by-online-data-railofy
https://brightdata.com/case-studies/data-intensive-analytical-solutions
https://brightdata.com/case-studies/canopy-advantage-solutions
https://brightdata.com/case-studies/seamless-digital-automations

与其他将整个文件加载到内存中的解析器不同,SAX增量处理文件,节省内存并提高性能。然而,SAX需要编写更多代码来动态管理每个数据段。此外,它无法重新访问和分析数据的特定部分。

如果您需要扫描一个大型XML文件(例如,包含各种事件的日志文件)以提取特定信息(例如,错误消息),SAX可以帮助您高效地浏览文件。然而,如果您的分析需要理解不同数据段之间的关系,SAX可能不是最佳选择。

untangle

untangle是一个轻量级的Python XML解析库,简化了从XML文档中提取数据的过程。与需要导航层次结构的传统XML解析器不同,untangle允许您直接将XML元素和属性作为Python对象访问。

使用untangle,您可以将XML文档转换为嵌套的Python字典,其中XML元素表示为字典键,属性和文本内容存储为对应的值。这种方法使得使用Python数据结构访问和操作XML数据变得容易。

untangle在Python中不可用,需要使用以下PyPI命令安装:

pip install untangle

以下示例演示如何使用untangle库解析XML文件并访问XML元素 :

import untangle
import requests

url = "https://brightdata.com/post-sitemap.xml"

response = requests.get(url)

if response.status_code == 200:

    obj = untangle.parse(response.text)

    for url in obj.urlset.url:
        print(url.loc.cdata.strip())
else:
    print("Failed to retrieve XML file from the URL.")

您的输出如下所示:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/addressing-brand-protection-from-every-angle
https://brightdata.com/case-studies/taking-control-of-the-digital-shelf-with-public-online-data
https://brightdata.com/case-studies/the-seo-transformation
https://brightdata.com/case-studies/data-driven-automated-e-commerce-tools
https://brightdata.com/case-studies/highly-targeted-influencer-marketing
https://brightdata.com/case-studies/data-driven-products-for-smarter-shopping-solutions
https://brightdata.com/case-studies/workplace-diversity-facilitated-by-online-data
https://brightdata.com/case-studies/alternative-travel-solutions-enabled-by-online-data-railofy
https://brightdata.com/case-studies/data-intensive-analytical-solutions
https://brightdata.com/case-studies/canopy-advantage-solutions
https://brightdata.com/case-studies/seamless-digital-automations

untangle提供了一种用户友好的方法,用于在Python中处理XML数据。它通过清晰的语法简化了解析过程,并自动将XML结构转换为易于使用的Python对象,消除了复杂的导航技术。然而,请记住,untangle需要单独安装,因为它不是核心Python包的一部分。

如果您有一个格式良好的XML文件,并需要快速将其转换为Python对象进行进一步处理,您应考虑使用untangle。例如,如果您有一个程序下载天气数据的XML格式文件,untangle可以很好地解析XML,并创建表示当前温度、湿度和天气预报的Python对象。然后,这些对象可以轻松地在您的应用程序中操作和显示。

结论

在本文中,您了解了有关XML文件以及在Python中解析XML文件的各种方法。

无论您是在处理小型配置文件、解析大型Web服务响应,还是从广泛的网站地图中提取数据,Python都提供了多种库来自动化和简化您的XML解析任务。然而,在不使用代理管理的情况下使用requests库从Web访问文件时,您可能会遇到配额限制和限流问题。Bright Data是一个屡获殊荣的代理网络,提供可靠高效的代理解决方案,确保数据检索和解析的顺利进行。有了Bright Data,您可以应对XML解析任务,而不必担心限制或中断。联系我们的销售团队了解更多信息。

想跳过整个抓取和解析过程吗?免费试用我们的数据集市场