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 *