Introducción a la biblioteca Python lxml

    lxml es una biblioteca de Python que permite un fácil manejo de archivos XML y HTML, y también se puede utilizar para web scraping. Hay muchos analizadores XML disponibles en el mercado, pero para obtener mejores resultados, los desarrolladores a veces prefieren escribir sus propios analizadores XML y HTML. Aquí es cuando entra en juego la biblioteca lxml. Los beneficios clave de esta biblioteca son que es fácil de usar, extremadamente rápido al analizar documentos grandes, muy bien documentado y proporciona una conversión fácil de datos a tipos de datos de Python, lo que resulta en una manipulación de archivos más sencilla.

    En este tutorial, profundizaremos en Python lxml biblioteca, comenzando por cómo configurarlo para diferentes sistemas operativos, y luego discutiendo sus beneficios y la amplia gama de funcionalidades que ofrece.

    Instalación

    Hay varias formas de instalar lxml en su sistema. Exploraremos algunos de ellos a continuación.

    Usando Pip

    Pepita es un administrador de paquetes de Python que se utiliza para descargar e instalar bibliotecas de Python en su sistema local con facilidad, es decir, también descarga e instala todas las dependencias para el paquete que está instalando.

    Si tiene pip instalado en su sistema, simplemente ejecute el siguiente comando en la terminal o en el símbolo del sistema:

    $ pip install lxml
    

    Usando apt-get

    Si está usando MacOS o Linux, puede instalar lxml ejecutando este comando en su terminal:

    $ sudo apt-get install python-lxml
    

    Usando easy_install

    Probablemente no llegue a esta parte, pero si ninguno de los comandos anteriores le funciona por alguna razón, intente usar easy_install:

    $ easy_install lxml
    

    Nota: Si desea instalar alguna versión particular de lxml, simplemente puede indicarlo cuando ejecute el comando en el símbolo del sistema o terminal como este, lxml==3.x.y.

    A estas alturas, debería tener una copia de la biblioteca lxml instalada en su máquina local. Ahora ensuciemos nuestras manos y veamos qué cosas interesantes se pueden hacer con esta biblioteca.

    Funcionalidad

    Para poder utilizar la biblioteca lxml en su programa, primero debe importarla. Puedes hacerlo usando el siguiente comando:

    from lxml import etree as et
    

    Esto importará el etree module, el módulo de nuestro interés, de la biblioteca lxml.

    Creación de documentos HTML / XML

    Utilizando la etree módulo, podemos crear elementos XML / HTML y sus subelementos, lo cual es algo muy útil si estamos tratando de escribir o manipular un archivo HTML o XML. Intentemos crear la estructura básica de un archivo HTML usando etree:

    root = et.Element('html', version="5.0")
    
    # Pass the parent node, name of the child node,
    # and any number of optional attributes
    et.SubElement(root, 'head')
    et.SubElement(root, 'title', bgcolor="red", fontsize="22")
    et.SubElement(root, 'body', fontsize="15")
    

    En el código anterior, debe saber que el Element La función requiere al menos un parámetro, mientras que la SubElement la función requiere al menos dos. Esto es porque el Element función sólo ‘requiere’ el nombre del elemento a crear, mientras que la SubElement La función requiere que se creen el nombre tanto del node raíz como del node hijo.

    También es importante saber que estas dos funciones solo tienen un límite inferior para el número de argumentos que pueden aceptar, pero ningún límite superior porque puede asociar tantos atributos como desee. Para agregar un atributo a un elemento, simplemente agregue un parámetro adicional a la función (Sub) Elemento y especifique su atributo en forma de attributeName="attribute value".

    Intentemos ejecutar el código que escribimos anteriormente para tener una mejor intuición con respecto a estas funciones:

    # Use pretty_print=True to indent the HTML output
    print (et.tostring(root, pretty_print=True).decode("utf-8"))
    

    Salida:

    <html version="5.0">
      <head/>
      <title bgcolor="red" fontsize="22"/>
      <body fontsize="15"/>
    </html>
    

    Hay otra forma de crear y organizar sus elementos de manera jerárquica. Exploremos eso también:

    root = et.Element('html')
    root.append(et.SubElement('head')) 
    root.append(et.SubElement('body'))
    

    Entonces, en este caso, cada vez que creamos un nuevo elemento, simplemente lo agregamos al node raíz / padre.

    Analizar documentos HTML / XML

    Hasta ahora, solo hemos considerado crear nuevos elementos, asignarles atributos, etc. Veamos ahora un ejemplo donde ya tenemos un archivo HTML o XML, y deseamos analizarlo para extraer cierta información. Suponiendo que tenemos el archivo HTML que creamos en el primer ejemplo, intentemos obtener el nombre de etiqueta de un elemento específico, seguido de imprimir los nombres de etiqueta de todos los elementos.

    print(root.tag)
    

    Salida:

    html 
    

    Ahora para iterar a través de todos los elementos secundarios en el root node e imprime sus etiquetas:

    for e in root:
        print(e.tag)
    

    Salida:

    head
    title
    body
    

    Trabajar con atributos

    Veamos ahora cómo asociamos atributos a elementos existentes, así como cómo recuperar el valor de un atributo en particular para un elemento dado.

    Usando el mismo root elemento como antes, pruebe el siguiente código:

    root.set('newAttribute', 'attributeValue') 
    
    # Print root again to see if the new attribute has been added
    print(et.tostring(root, pretty_print=True).decode("utf-8"))
    

    Salida:

    <html version="5.0" newAttribute="attributeValue">
      <head/>
      <title bgcolor="red" fontsize="22"/>
      <body fontsize="15"/>
    </html>
    

    Aquí podemos ver que el newAttribute="attributeValue" de hecho, se ha agregado al elemento raíz.

    Intentemos ahora obtener los valores de los atributos que hemos establecido en el código anterior. Aquí accedemos a un elemento hijo usando la indexación de matriz en el root elemento, y luego use el get() método para recuperar el atributo:

    print(root.get('newAttribute'))
    print(root[1].get('alpha')) # root[1] accesses the `title` element
    print(root[1].get('bgcolor'))
    

    Salida:

    attributeValue
    None
    red
    

    Recuperar texto de elementos

    Ahora que hemos visto las funcionalidades básicas del etree módulo, intentemos hacer algunas cosas más interesantes con nuestros archivos HTML y XML. Casi siempre, estos archivos tienen algo de texto entre las etiquetas. Entonces, veamos cómo podemos agregar texto a nuestros elementos:

    # Copying the code from the very first example
    root = et.Element('html', version="5.0")
    et.SubElement(root, 'head')
    et.SubElement(root, 'title', bgcolor="red", fontsize="22")
    et.SubElement(root, 'body', fontsize="15")
    
    # Add text to the Elements and SubElements
    root.text = "This is an HTML file"
    root[0].text = "This is the head of that file"
    root[1].text = "This is the title of that file"
    root[2].text = "This is the body of that file and would contain paragraphs etc"
    
    print(et.tostring(root, pretty_print=True).decode("utf-8"))
    

    Salida:

    <html version="5.0">This is an HTML file<head>This is the head of that file</head><title bgcolor="red" fontsize="22">This is the title of that file</title><body fontsize="15">This is the body of that file and would contain paragraphs etc</body></html>
    

    Compruebe si un elemento tiene hijos

    A continuación, hay dos cosas muy importantes que deberíamos poder verificar, ya que se requieren en muchas aplicaciones de raspado web para el manejo de excepciones. Lo primero que nos gustaría verificar es si un elemento tiene hijos o no, y lo segundo es si un node es un Element.

    Hagamos eso para los nodes que creamos arriba:

    if len(root) > 0:
        print("True")
    else:
        print("False")
    

    El código anterior dará como resultado “Verdadero” ya que el node raíz tiene nodes secundarios. Sin embargo, si verificamos lo mismo para los nodes secundarios de la raíz, como en el código siguiente, el resultado será “Falso”.

    for i in range(len(root)):
        if (len(root[i]) > 0):
            print("True")
        else:
            print("False")
    

    Salida:

    False
    False
    False
    

    Ahora hagamos lo mismo para ver si cada uno de los nodes es un Element O no:

    for i in range(len(root)):
        print(et.iselement(root[i]))
    

    Salida:

    True
    True
    True
    

    los iselement El método es útil para determinar si tiene un Element objeto y, por lo tanto, si puede continuar atravesándolo utilizando los métodos que hemos mostrado aquí.

    Compruebe si un elemento tiene un padre

    Justo ahora, mostramos cómo bajar en la jerarquía, es decir, cómo verificar si un elemento tiene hijos o no, y ahora en esta sección intentaremos subir la jerarquía, es decir, cómo verificar y obtener el padre de un node hijo .

    print(root.getparent())
    print(root[0].getparent())
    print(root[1].getparent())
    

    La primera línea no debería devolver nada (también conocido como None) ya que el node raíz en sí no tiene ningún padre. Los otros dos deben apuntar al elemento raíz, es decir, la etiqueta HTML. Revisemos la salida para ver si es lo que esperamos:

    Salida:

    None
    <Element html at 0x1103c9688>
    <Element html at 0x1103c9688>
    

    Recuperando elementos hermanos

    En esta sección, aprenderemos a recorrer los lados de la jerarquía, lo que recupera los hermanos de un elemento en el árbol.

    Atravesar el árbol de lado es bastante similar a navegar verticalmente. Para este último, usamos el getparent y la longitud del elemento, para el primero, usaremos getnext y getprevious funciones. Probémoslos en nodes que creamos previamente para ver cómo funcionan:

    # root[1] is the `title` tag
    print(root[1].getnext()) # The tag after the `title` tag
    print(root[1].getprevious()) # The tag before the `title` tag
    

    Salida:

    <Element body at 0x10b5a75c8>
    <Element head at 0x10b5a76c8>
    

    Aqui puedes ver eso root[1].getnext() recuperó la etiqueta “body” ya que era el siguiente elemento, y root[1].getprevious() recuperó la etiqueta “cabeza”.

    Del mismo modo, si hubiéramos utilizado el getprevious función en la raíz, habría devuelto None, y si hubiéramos usado el getnext función en la raíz[2], también habría vuelto None.

    Analizar XML desde una cadena

    Continuando, si tenemos un archivo XML o HTML y deseamos analizar la cadena sin procesar para obtener o manipular la información requerida, podemos hacerlo siguiendo el ejemplo a continuación:

    root = et.XML('<html version="5.0">This is an HTML file<head>This is the head of that file</head><title bgcolor="red" fontsize="22">This is the title of that file</title><body fontsize="15">This is the body of that file and would contain paragraphs etc</body></html>')
    root[1].text = "The title text has changed!"
    print(et.tostring(root, xml_declaration=True).decode('utf-8'))
    

    Salida:

    <?xml version='1.0' encoding='ASCII'?>
    <html version="5.0">This is an HTML file<head>This is the head of that file</head><title bgcolor="red" fontsize="22">The title text has changed!</title><body fontsize="15">This is the body of that file and would contain paragraphs etc</body></html>
    

    Como puede ver, cambiamos con éxito algún texto en el documento HTML. La declaración de tipo de documento XML también se agregó automáticamente debido a la xml_declaration parámetro que pasamos al tostring función.

    Buscando elementos

    Lo último que vamos a discutir es bastante útil al analizar archivos XML y HTML. Comprobaremos las formas a través de las cuales podemos ver si un Element tiene algún tipo de hijos en particular, y si los tiene, qué contienen.

    Esto tiene muchos casos de uso prácticos, como encontrar todos los elementos de enlace en una página web en particular.

    print(root.find('a')) # No <a> tags exist, so this will be `None`
    print(root.find('head').tag)
    print(root.findtext('title')) # Directly retrieve the the title tag's text
    

    Salida:

    None
    head
    This is the title of that file
    

    Conclusión

    En el tutorial anterior, comenzamos con una introducción básica a qué es la biblioteca lxml y para qué se usa. Después de eso, aprendimos cómo instalarlo en diferentes entornos como Windows, Linux, etc. Continuando, exploramos diferentes funcionalidades que podrían ayudarnos a atravesar el árbol HTML / XML tanto vertical como lateralmente. Al final, también discutimos formas de encontrar elementos en nuestro árbol y de obtener información de ellos.

     

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *