Introducción a la biblioteca lxml de Python

lxml es una biblioteca de Python que permite el manejo fácil de archivos XML y HTML, y también se puede utilizar para raspar la web. Hay muchos analizadores XML listos para usar, pero para obtener mejores resultados, los desarrolladores a veces prefieren escribir sus propios analizadores XML y HTML. Esto es cuando la biblioteca lxml viene a jugar. 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 fácil conversión 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 la biblioteca lxml de Python , comenzando con la configuración de los 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. Vamos a explorar algunos de ellos a continuación.

Usando pip

Pip es un administrador de paquetes de Python que se usa para descargar e instalar las 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 el terminal o en el símbolo del sistema:
$ pip install lxml

Utilizando apt-get

Si está utilizando 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 por alguna razón ninguno de los comandos anteriores funciona, intente usar easy_install:
$ easy_install lxml
Nota: Si desea instalar cualquier versión particular de lxml, puede indicar simplemente que cuando se ejecuta el comando en el símbolo del sistema o terminal como este, lxml==3.x.y.
En este momento, debe tener una copia de la biblioteca lxml instalada en su máquina local. Ensuciémonos ahora y veamos qué cosas geniales se pueden hacer usando 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 etreemódulo, el módulo de nuestro interés, de la biblioteca lxml.

Creación de documentos HTML / XML

Usando el etreemódulo, podemos crear elementos XML / HTML y sus subelementos, lo cual es 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, necesita saber que la Elementfunción requiere al menos un parámetro, mientras que la SubElementfunción requiere al menos dos. Esto se debe a que la Elementfunción solo 'requiere' el nombre del elemento que se creará, mientras que la SubElementfunción requiere que se creen tanto el nodo raíz como el nodo secundario.
También es importante saber que estas dos funciones solo tienen un límite inferior al número de argumentos que pueden aceptar, pero no un 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 la forma de attributeName='attribute value'.
Intentemos ejecutar el código que escribimos anteriormente para obtener 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 manera de crear y organizar sus elementos de una manera jerárquica. Vamos a explorar eso también:
root = et.Element('html')  
root.append(et.SubElement('head'))  
root.append(et.SubElement('body'))  
Entonces, en este caso, cuando creamos un nuevo elemento, simplemente lo agregamos al nodo raíz / padre.

Análisis de documentos HTML / XML

Hasta ahora, solo hemos considerado crear nuevos elementos, asignarles atributos, etc. Ahora veamos 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, tratemos de obtener el nombre de etiqueta de un elemento específico, seguido de la impresión de los nombres de etiqueta de todos los elementos.
print(root.tag)  
Salida:
html  
Ahora para recorrer todos los elementos secundarios del rootnodo e imprimir sus etiquetas:
for e in root:  
    print(e.tag)
Salida:
head  
title  
body  

Trabajando con atributos

Veamos ahora cómo asociamos los atributos a los elementos existentes , así como cómo recuperar el valor de un atributo particular para un elemento dado.
Usando el mismo rootelemento que 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 newAttribute="attributeValue"efectivamente se ha agregado al elemento raíz.
Ahora intentemos obtener los valores de los atributos que hemos establecido en el código anterior. Aquí accedemos a un elemento secundario utilizando la indexación de matriz en el rootelemento, y luego usamos 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 funcionalidades básicas del etreemódulo, intentemos hacer algunas cosas más interesantes con nuestros archivos HTML y XML. Casi siempre, estos archivos tienen algún 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>  

Comprobar si un elemento tiene hijos

A continuación, hay dos cosas muy importantes que debemos poder verificar, ya que esto se requiere en muchas aplicaciones de rastreo web para el manejo de excepciones. Lo primero que nos gustaría comprobar es si un elemento tiene hijos o no, y lo segundo es si un nodo es o no Element.
Vamos a hacer eso para los nodos que creamos anteriormente:
if len(root) > 0:  
    print("True")
else:  
    print("False")
El código anterior dará como resultado "Verdadero", ya que el nodo raíz tiene nodos secundarios. Sin embargo, si comprobamos lo mismo para los nodos secundarios de la raíz, como en el código a continuación, la salida 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 nodos es Elemento no:
for i in range(len(root)):  
    print(et.iselement(root[i]))
Salida:
True  
True  
True  
El iselementmétodo es útil para determinar si tiene un Elementobjeto válido y, por lo tanto, si puede continuar recorriéndolo con los métodos que hemos mostrado aquí.

Comprobar si un elemento tiene un padre

En este momento, mostramos cómo bajar la jerarquía, es decir, cómo verificar si un elemento tiene hijos o no, y ahora, en esta sección, trataremos de subir la jerarquía, es decir, cómo verificar y obtener el padre de un nodo secundario .
print(root.getparent())  
print(root[0].getparent())  
print(root[1].getparent())  
La primera línea no debe devolver nada (aka None) ya que el nodo raíz en sí no tiene ningún padre. Los otros dos deberían 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 Elemento Hermanos

En esta sección aprenderemos cómo atravesar los lados en la jerarquía, lo que recupera los hermanos de un elemento en el árbol.
Atravesar el árbol lateralmente es muy similar a navegar verticalmente. Para el último, usamos el getparenty la longitud del elemento, para el primero, usaremos getnextgetpreviousfunciones. Probémoslos en nodos que creamos anteriormente 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>  
Aquí puede ver que se root[1].getnext()recuperó la etiqueta "cuerpo" ya que era el elemento siguiente, y se root[1].getprevious()recuperó la etiqueta "cabeza".
De manera similar, si hubiéramos usado la getpreviousfunción en la raíz, habría regresado None, y si hubiéramos usado la getnextfunción en la raíz [2], también habría regresado None.

Analizar XML desde una cadena

Continuando, si tenemos un archivo XML o HTML y deseamos analizar la cadena en bruto para obtener o manipular la información requerida, podemos hacerlo siguiendo el siguiente ejemplo:
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 un texto en el documento HTML. La declaración de doctype XML también se agregó automáticamente debido al xml_declarationparámetro que pasamos a la tostringfunción.

Buscando elementos

Lo último que vamos a discutir es bastante útil al analizar archivos XML y HTML. Estaremos revisando las maneras en que podemos ver si una Elementtiene algún tipo particular de hijos y si hace qué contienen.
Esto tiene muchos casos prácticos de uso, 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 de qué es la biblioteca lxml y para qué se utiliza. Después de eso, aprendimos cómo instalarlo en diferentes entornos como Windows, Linux, etc. Pasando a la exploración, exploramos diferentes funcionalidades que podrían ayudarnos a atravesar el árbol HTML / XML tanto verticalmente como lateralmente. Al final, también discutimos formas de encontrar elementos en nuestro árbol y también de obtener información de ellos.

Acerca de: Programator

Somos Instinto Programador

0 comentarios:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

Con tecnología de Blogger.