En este artículo se introducirá el uso de la biblioteca BeautifulSoup 4 en Python 2, por lo que se suponen mínimos conocimientos de este lenguaje. La biblioteca en su versión 4 también permite el uso de Python 3, pero puede dar diversos errores por lo que es preferible usar la versión 2 de dicho lenguage. Se supone conocimiento también de la estructuración de documentos HTML y las etiquetas más usuales.
¿Qué es BeautifulSoup?
BeautifulSoup es una biblioteca de Python para extraer contenido de ficheros HTML y XML. Resulta muy útil para obtener información de forma procesable (en un sistema de árbol fácil de manejar) de páginas web.
Instalación
Debian y derivados
Si aún no tienes Python instalado en tu sistema, se puede instalar a través de apt:
# apt-get install python2.7 python-pip
con dicho comando se instalará la última versión actualmente disponible de Python 2 y PyPi, un gestor de módulos python muy útil para instalar diversas bibliotecas de este lenguaje.
Finalmente, para instalar BeautifulSoup:
# apt-get install python-bs4`
PyPi
En sistemas distintos a GNU/Linux, lo más cómodo es instalar BeautifulSoup a través de este gestor. Antes de ello deberemos haber instalado Python 2, el cual se puede descargar desde su la página web de python. Asegúrate que en el instalador seleccionas la opción de instalar _pip_. Después, abre una consola de comandos y ejecuta
# pip install beautifulsoup4
Instalación del lector de HTML
Para extraer el contenido de los documentos HTML o XML, es necesario instalar un lector. BeautifulSoup soporta el lector integrado en Python, pero tiene algunos inconvenientes. En este artículo trabajaremos con _lxml_, al ser el más rápido, aunque lógicamente tiene otros inconvenientes también. Para ver el lector que más se ajusta a tus necesidades, consulta la tabla de la documentación oficial.
Para instalar _lxml_, ejecuta
# apt-get install python-lxml
en Debian o
# pip install lxml
Nota
El único lector XML es _lxml-xml_, por lo que si tu intención es trabajar con ese tipo de documentos no hay alternativa (aún).
Uso básico
Creamos un nuevo archivo de Python (.py) en el cual lo primero es importar el módulo de BeautifulSoup:
from bs4 import BeautifulSoup.
además del lector y de _urllib2_ para leer páginas web:
import lxml, urllib2
Antes de comenzar a programar, es bueno tener una vista rápida de la estructura de la página web en cuestión, por lo que es útil abrir cualquier navegador web e “Inspeccionar elemento”, para ver los _id_ de cada elemento, sus etiquetas y demás información que nos sea útil después para agilizar el trabajo.
En el documento .py anteriormente comenzado, añadimos las siguientes dos líneas:
url = urllib2.urlopen("https://es.wikipedia.org/wiki/Debian_GNU/Linux") # leer la web con urllib2
soup = BeautifulSoup(url,"lxml") # crear el objeto BeautifulSoup
El objeto BeautifulSoup, guardado en la variable soup, es el que contiene la información del documento HTML completo, en este caso vamos a usar la página de Wikipedia sobre Debian
Accediendo por las etiquetas
Las etiquetas en BeautifulSoup se corresponden a las etiquetas de los documentos HTML, por lo que para acceder al título podemos escribir:
soup.title # <title>Debian GNU/Linux - Wikipedia, la enciclopedia libre</title>
soup.title.name # title
soup.title.string # Debian GNU/Linux - Wikipedia, la enciclopedia libre
Donde se puede apreciar la diferencia entre los atributos _name_ y _string_. Como se ve en el ejemplo, si no se especifica ningún atributo se obtiene el texto en HTML tal cual está.
Si hay varias etiquetas iguales, como pueden ser las _a_, al escribir `soup.a` solo se accede a la primera etiqueta de dicho tipo. Para acceder a otra que no sea la primera, se puede crear una lista con
alst = soup.find_all('a'
y a partir de ella se puede acceder a los índices de cada elemento con
alist[i]
donde y es el índice del elemento _a_ al que se quiere acceder, empezando desde 0.
Para acceder al contenido de un atributo en particular, como puede ser el _id_ de un encabezado, se usa el siguiente formato:
soup.ETIQUETA['ATRIBUTO']
un ejemplo de esta última parte, usando
find_all
y accediendo a atributos, es:
alist = soup.find_all('a') # [<a id="top"></a>, ..., <a href="//www.mediawiki.org/"><img alt="Powered by MediaWiki" height="31" src="/static/images/poweredby_mediawiki_88x31.png" srcset="/static/images/poweredby_mediawiki_132x47.png 1.5x, /static/images/poweredby_mediawiki_176x62.png 2x" width="88"/></a>]
print alist[3] # elemento 4 de la lista (empieza desde 0): <a href="/wiki/GNU" title="GNU">GNU</a>
print alist[3]['href'] # atributo href del elemento 4: /wiki/GNU
print alist[3]['title'] # atributo title del elemento 4: GNU
Accediendo a través de los hijos
En el apartado anterior se ha visto como acceder a través de las etiquetas del documento. Ahora, recorreremos dicho documento de forma jerárquica en forma de árbol.
Para obtener los niveles inferiores a una etiqueta, por ejemplo a la etiqueta _head_, escribimos el siguiente código:
soup.head.contents
lo que nos devolverá una lista con las distintas etiquetas, cada una un elemento de la lista. Para acceder a cada elemento de dicha lista, lo hacemos de la manera habitual en Python, con corchetes:
soup.head.contents[i] # acceder al elemento i-1 de la lista
Al ser una estructura de árbol, se puede acceder al elemento superior a uno dado, por ejemplo, si estamos en la etiqueta _title_, podemos “escalar” hasta la etiqueta _head_:
soup.title.parent
lo que nos muestra toda la información contenida en _head_. También es posible concatenar _parent_,
soup.title.parent.parent
lo que en este caso nos devolvería el HTML completo.
Documentación
Toda la documentación sobre esta biblioteca se encuentra en https://www.crummy.com/software/BeautifulSoup/bs4/doc/, la cual es muy completa y aporta gran variedad de ejemplos.
CC-BY Creative Commons.