Guía sobre cómo realizar el parseo de XML en Python

Aprenda a realizar el parseo de XML en Python utilizando bibliotecas como ElementTree, lxml y SAX para mejorar sus proyectos de procesamiento de datos.
2 min de lectura
How to parse XML in Python main blog image

El lenguaje de marcado extensible (XML) es un formato muy utilizado para almacenar e intercambiar datos estructurados. Los archivos XML se utilizan habitualmente para representar datos jerárquicos, como archivos de configuración, formatos de intercambio de datos, respuestas de servicios web y mapas de sitios web.

El parseo de archivos XML en Python es una tarea habitual, especialmente para automatizar procesos manuales como el procesamiento de datos recuperados de API web o el Scraping web.

En este artículo, aprenderás algunas de las bibliotecas que puedes utilizar para el parseo de XML en Python, incluyendo el móduloElementTree, la biblioteca lxml, minidom, Simple API for XML (SAX) y untangle.

Conceptos clave de un archivo XML

Antes de aprender a realizar el parseo de XML en Python, debes comprender qué es la definición de esquema XML (XSD) y qué elementos componen un archivo XML. Esta comprensión puede ayudarte a seleccionar la biblioteca Python adecuada para tu tarea de parseo.

XSD es una especificación de esquema que define la estructura, el contenido y los tipos de datos permitidos en un documento XML. Sirve como sintaxis para validar la estructura y el contenido de los archivos XML con respecto a un conjunto predefinido de reglas.

Un archivo XML suele incluir los elementos espacio de nombres, raíz, atributos, elementos y contenido de texto, que en conjunto representan datos estructurados.

  • Espacio de nombres
  • raíz
  • atributos
  • elementos
  • contenido de texto

Por ejemplo, el mapa del sitio de Bright Data tiene la siguiente estructura XML:

  • urlset es el elemento raíz.
  • <urlset xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd> es la declaración del espacio de nombres específico del elemento urlset, lo que implica que las reglas de esta declaración se extienden al elemento urlset. Todos los elementos que se encuentran debajo deben ajustarse al esquema descrito por este espacio de nombres.
  • url es el primer elemento secundario del elemento raíz.
  • loc es el elemento secundario del elemento url.

Ahora que sabes un poco más sobre XSD y los elementos de los archivos XML, utilicemos esa información para ayudar al parseo de un archivo XML con algunas bibliotecas.

Varias formas de realizar el parseo de XML en Python

A modo de demostración, para este tutorial utilizarás el mapa del sitio de Bright Data, que está disponible en formato XML. En los siguientes ejemplos, el contenido del mapa del sitio de Bright Data se obtiene utilizando labiblioteca de solicitudes de Python.

La biblioteca de solicitudes de Python no está integrada, por lo que debe instalarla antes de continuar. Puede hacerlo utilizando el siguiente comando:

pip install requests

ElementTree

La API XML ElementTreeproporciona una API sencilla e intuitiva para el parseo y la creación de datos XML en Python. Es un módulo integrado en la biblioteca estándar de Python, lo que significa que no es necesario instalar nada explícitamente.

Por ejemplo, puede utilizar el métodofindall()para buscar todos los elementosurldesde la raíz e imprimir el valor de texto del elementoloc, de esta manera:

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("No se pudo recuperar el archivo XML de la URL.")

Todas las URL del mapa del sitio se imprimen en la salida:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/Addressing la protección de marca desde todos los ángulos
https://brightdata.com/case-studies/Taking control del estante digital con datos públicos en línea
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 es una forma fácil de realizar el parseo de datos XML en Python, con una API sencilla que facilita la navegación y la manipulación de estructuras XML. Sin embargo, ElementTree tiene sus limitaciones: carece de un soporte sólido para la validación de esquemas y no es ideal si necesitas garantizar un cumplimiento estricto de una especificación de esquema antes del parseo.

Si tiene un pequeño script que lee una fuente RSS, la API fácil de usar de ElementTree sería una herramienta útil para extraer títulos, descripciones y enlaces de cada elemento de la fuente. Sin embargo, si tiene un caso de uso con validación compleja o archivos masivos, sería mejor considerar otra biblioteca como lxml.

lxml

lxmles una API rápida, fácil de usar y con muchas funciones para el parseo de archivos XML en Python; sin embargo, no es una biblioteca precompilada en Python. Aunque algunas plataformas Linux y Mac ya tienen instalado el paquete lxml, otras plataformas necesitan una instalación manual.

lxml se distribuye a través dePyPIy se puedeinstalarutilizando el siguiente comandopip:

pip install lxml

Una vez instalada, puede utilizarlxmlpara realizar el parseo de archivos XML utilizandovariosmétodosAPI, comofind(),findall(),findtext(),get() yget_element_by_id().

Por ejemplo, puede utilizar el métodofindall()para iterar sobre los elementosurl, encontrar sus elementosloc(que son elementos secundarios del elementourl) y, a continuación, imprimir el texto de la ubicación utilizando el siguiente código:

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("No se pudo recuperar el archivo XML de la URL.")

La salida muestra todas las URL encontradas en el mapa del sitio:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/Addressing la protección de marca desde todos los ángulos
https://brightdata.com/case-studies/Taking control del estante digital con datos públicos en línea
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

Hasta ahora, has aprendido a buscar elementos e imprimir su valor. Ahora, exploremos la validación del esquema antes del Parseo del XML. Este proceso garantiza que el archivo se ajuste a la estructura especificada definida por el esquema.

El XSD para el mapa del sitio tiene este aspecto:

<?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>

Para utilizar el mapa del sitio para la validación del esquema, asegúrese de copiarlo manualmente y crear un archivo llamado schema.xsd.

Para validar el archivo XML utilizando este XSD, utilice el siguiente código:


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 es válido según el esquema.")
    except etree.DocumentInvalid as e:
        print("Error de validación XML:", e)

Aquí, se realiza el parseo del archivo XSD utilizando el métodoetree.parse(). A continuación, se crea un esquema XML utilizando el contenido del documento XSD analizado. Por último, se valida el documento raíz XML con respecto al esquema XML utilizando el métodoassertValid(). Si la validación del esquema se supera, la salida incluye un mensaje que dice algo así como«XML válido según el esquema». De lo contrario, se genera la excepciónDocumentInvalid.

El resultado debería ser similar al siguiente:

 Validación del esquema:
    El XML es válido según el esquema.

Ahora, leamos un archivo XML que utiliza el método xpath para buscar los elementos utilizando su ruta.

Para leer los elementos utilizando el método xpath(), utilice el siguiente código:

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("Compatibilidad con XPath:")
    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())

En este código, se registra el prefijo del espacio de nombres ns y se asigna al URI del espacio de nombres http://www.sitemaps.org/schemas/sitemap/0.9. En la expresión XPath, se utiliza el prefijo ns para especificar elementos en el espacio de nombres. Por último, la expresión .//ns:url/ns:loc selecciona todos los elementos loc que son hijos de elementos url en el espacio de nombres.

El resultado será similar al siguiente:

Compatibilidad con XPath:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/Addressing la protección de marca desde todos los ángulos
https://brightdata.com/case-studies/Taking control del estante digital con datos públicos en línea
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

Como puede ver, los métodos find() y findall() son más rápidos que el método xpath, ya que este último recopila todos los resultados en la memoria antes de devolverlos. Se recomienda utilizar el método find(), a menos que exista una razón específica para utilizar consultas XPath.

lxml ofrece potentes funciones para el parseo y la manipulación de XML y HTML. Admite consultas complejas medianteexpresiones XPath, valida documentos con esquemas e incluso permitetransformaciones de lenguaje de hojas de estilo extensibles (XSLT). Esto lo hace ideal para situaciones en las que el rendimiento y la funcionalidad avanzada son cruciales. Sin embargo, tenga en cuenta que lxml requiere una instalación independiente, ya que no forma parte del paquete básico de Python.

Si se trabaja con datos XML grandes o complejos que requieren un alto rendimiento y una manipulación avanzada, se debe considerar el uso de lxml. Por ejemplo, si se procesan fuentes de datos financieros en formato XML, es posible que se necesite utilizar expresiones XPath para extraer elementos específicos, como los precios de las acciones, validar los datos con respecto a un esquema financiero para garantizar su precisión y, potencialmente, transformar los datos utilizando XSLT para su posterior análisis.

minidom

minidomes una biblioteca de parseo XML ligera y sencilla que se incluye en la biblioteca estándar de Python. Aunque no es tan rica en funciones ni tan eficiente como el parseo con lxml, ofrece una forma sencilla de analizar y manipular datos XML en Python.

Puede utilizar los distintos métodos disponibles en el objeto DOM para acceder a los elementos. Por ejemplo, puede utilizar elmétodogetElementsByTagName()para recuperar el valor de un elemento utilizando su nombre de etiqueta.

El siguiente ejemplo muestra cómo utilizar la biblioteca minidom para realizar el parseo de un archivo XML y recuperar los elementos utilizando sus nombres de etiqueta:

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.")

El resultado sería similar a este:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/Addressing la protección de marca desde todos los ángulos
https://brightdata.com/case-studies/Taking control del estante digital con datos públicos en línea
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 trabaja con datos XML representándolos como un árbol DOM. Esta estructura de árbol facilita la navegación y la manipulación de datos, y es ideal para tareas básicas como leer, cambiar o crear estructuras XML sencillas.

Si su programa implica leer la configuración predeterminada de un archivo XML, el enfoque DOM de minidom le permite acceder fácilmente a configuraciones específicas dentro del archivo XML utilizando métodos como la búsqueda de nodos secundarios o atributos. Con minidom, puede recuperar fácilmente configuraciones específicas del archivo XML, como el nodo font-size, y utilizar su valor dentro de su aplicación.

Analizador SAX

Elanalizador SAXes un enfoque de parseo XML basado en eventos en Python que procesa documentos XML de forma secuencial y genera eventos a medida que encuentra diversas partes del documento. A diferencia de los analizadores basados en DOM, que construyen una estructura de árbol que representa todo el documento XML en la memoria, los analizadores SAX no crean una representación completa del documento. En su lugar, emiten eventos como etiquetas de inicio, etiquetas de fin y contenido de texto a medida que analizan el documento.

Los analizadores SAX son adecuados para procesar archivos XML grandes o flujos en los que la eficiencia de la memoria es importante, ya que operan sobre los datos XML de forma incremental sin cargar todo el documento en la memoria.

Al utilizar el analizador SAX, es necesario definir los controladores de eventos que responden a eventos XML específicos, como startElement y endElement emitidos por el analizador. Estos controladores de eventos se pueden personalizar para realizar acciones basadas en la estructura y el contenido del documento XML.

El siguiente ejemplo muestra cómo realizar el parseo de un archivo XML utilizando el analizador SAX definiendo los eventos startElement y endElement y recuperando la información de la URL del archivo sitemap:

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":
            imprimir(self.url.strip())
            self.url = ""
            self.in_url = False
        elif nombre == "loc":
            self.in_loc = False

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

respuesta = requests.get(url)
si respuesta.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.")

El resultado sería similar a este:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/Addressing la protección de marca desde todos los ángulos
https://brightdata.com/case-studies/Taking control del estante digital con datos públicos en línea
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

A diferencia de otros analizadores que cargan todo el archivo en la memoria, SAX procesa los archivos de forma incremental, lo que ahorra memoria y mejora el rendimiento. Sin embargo, SAX requiere escribir más código para gestionar cada segmento de datos de forma dinámica. Además, no puede volver a visitar y analizar partes específicas de los datos más adelante.

Si necesita escanear un archivo XML grande (por ejemplo, un archivo de registro que contiene varios eventos) para extraer información específica (por ejemplo, mensajes de error), SAX puede ayudarle a navegar de manera eficiente por el archivo. Sin embargo, si su análisis requiere comprender las relaciones entre diferentes segmentos de datos, es posible que SAX no sea la mejor opción.

untangle

untanglees una biblioteca ligera de parseo de XML para Python que simplifica el proceso de extracción de datos de documentos XML. A diferencia de los analizadores XML tradicionales que requieren navegar por estructuras jerárquicas, untangle le permite acceder a los elementos y atributos XML directamente como objetos Python.

Con untangle, puede convertir documentos XML en diccionarios Python anidados, donde los elementos XML se representan como claves de diccionario y sus atributos y contenido de texto se almacenan como valores correspondientes. Este enfoque facilita el acceso y la manipulación de datos XML utilizando estructuras de datos Python.

untangle no está disponible de forma predeterminada en Python y debe instalarse utilizando el siguiente comando PyPI:

pip install untangle

El siguiente ejemplo muestra cómo realizar el parseo del archivo XML utilizando la biblioteca untangle y acceder a los elementos 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.")

El resultado será similar al siguiente:

https://brightdata.com/case-studies/powerdrop-case-study
https://brightdata.com/case-studies/Addressing la protección de marca desde todos los ángulos
https://brightdata.com/case-studies/Taking control del estante digital con datos públicos en línea
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 ofrece un enfoque fácil de usar para trabajar con datos XML en Python. Simplifica el proceso de parseo con una sintaxis clara y convierte automáticamente la estructura XML en objetos Python fáciles de usar, lo que elimina la necesidad de técnicas de navegación complejas. Sin embargo, ten en cuenta que untangle requiere una instalación separada, ya que no forma parte del paquete principal de Python.

Deberías considerar el uso de untangle si tienes un archivo XML bien formado y necesitas convertirlo rápidamente en objetos Python para su posterior procesamiento. Por ejemplo, si tienes un programa que descarga datos meteorológicos en formato XML, untangle podría ser una buena opción para realizar el parseo del XML y crear objetos Python que representen la temperatura, la humedad y la previsión meteorológica actuales. Estos objetos podrían manipularse y mostrarse fácilmente dentro de tu aplicación.

Conclusión

En este artículo, ha aprendido todo sobre los archivos XML y los distintos métodos de parseo en Python.

Tanto si trabaja con pequeños archivos de configuración, realiza el parseo de grandes respuestas de servicios web o extrae datos de extensos mapas de sitios, Python ofrece bibliotecas versátiles para automatizar y optimizar sus tareas de parseo de XML. Sin embargo, al acceder a archivos desde la web utilizando la biblioteca de solicitudes sin gestión de Proxy, es posible que se encuentre con excepciones de cuota y problemas de limitación.Bright Dataes una red de Proxy galardonada que proporcionasoluciones de Proxyfiables y eficientes para garantizar una recuperación y un parseo de datos sin problemas. Con Bright Data, puede abordar las tareas de parseo XML sin preocuparse por las limitaciones o las interrupciones. Contáctenos para obtener más información.

¿Quiere saltarse todo el proceso de scraping y Parseo? ¡Pruebe nuestro mercado de conjuntos de datos de forma gratuita!