可扩展标记语言(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
是根元素
的第一个子元素。loc
是url
元素的子元素。
现在,您对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事件的事件处理程序,例如解析器发出的startElement
和endElement
事件。这些事件处理程序可以根据XML文档的结构和内容执行自定义操作。
以下示例演示如何使用SAX解析器解析XML文件,通过定义startElement
和endElement
事件并从网站地图文件中检索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解析任务,而不必担心限制或中断。联系我们的销售团队了解更多信息。
想跳过整个抓取和解析过程吗?免费试用我们的数据集市场!