Introducción a Beautifulsoup en Python
Tabla de contenido
Introducción #
BeautifulSoup es una librería de Python que permite extraer información de archivos HTML y XML. Fue diseñada para hacer que el webscraping, o la extracción de datos de sitios web, sea más accesible y fácil de hacer. Convierte los archivos HTML y XML en árboles de parseo, que son estructuras de datos que representan la jerarquía de los elementos en el archivo.
Instalación #
Para comenzar, necesitarás instalar BeautifulSoup. Puedes hacerlo utilizando pip:
pip install beautifulsoup4
También necesitarás la librería requests
para hacer solicitudes HTTP:
pip install requests
Uso Básico de BeautifulSoup #
Primero, importa las librerías necesarias:
from bs4 import BeautifulSoup
import requests
Ahora vamos a realizar una solicitud HTTP para obtener el HTML de una página web:
# Definimos la url a scrapear.
url = 'https://es.wikipedia.org/wiki/Beautiful_Soup'
response = requests.get(url)
# Comprobamos que la solicitud se completó exitosamente
response.status_code == 200
## True
A continuación, pasamos el contenido de la respuesta (el HTML de la página web) a BeautifulSoup:
soup = BeautifulSoup(response.content, 'html.parser')
Ahora puedes usar la variable soup
para interactuar con el HTML de la página web. Por ejemplo, puedes buscar todos los encabezados de nivel 1:
h1_tags = soup.find_all('h1')
for tag in h1_tags:
print(tag.text)
## Beautiful Soup
Este código buscará todos los elementos <h1>
en el HTML y luego imprimirá el texto contenido en cada uno de ellos.
Buscar elementos con ciertos atributos #
Puedes buscar elementos que tengan ciertos atributos. Por ejemplo, podrías buscar todos los enlaces que apuntan a una página externa:
external_links = soup.find_all('a', attrs={'class':'external text'})
for link in external_links:
print(link['href'])
## http://www.crummy.com/software/BeautifulSoup/
## https://code.launchpad.net/beautifulsoup/
## http://www.crummy.com/software/BeautifulSoup/#Download
## http://www.crummy.com/software/BeautifulSoup/
## https://www.archlinux.org/packages/python2-beautifulsoup4
## https://aur.archlinux.org/packages/python2-beautifulsoup3/
## https://directory.fsf.org/wiki/Beautiful_Soup
## https://packages.gentoo.org/packages/dev-python/beautifulsoup
## https://www.openhub.net/p/p_10784
Este código buscará todos los elementos <a>
que tengan un atributo target
igual a _blank
, y luego imprimirá el enlace (el atributo href
) de cada uno.
Navegación del Árbol HTML con BeautifulSoup #
BeautifulSoup proporciona diferentes métodos para navegar y buscar a través del árbol de parseo. Los elementos más comunes son .contents
, .children
, .parent
, .next_sibling
, .prev_sibling
.
html_doc = """
<body>
<h1>El tutorial de BeautifulSoup</h1>
<div class="links">
<p class="link"><a href="http://example1.com" class="sister" id="link1">Ejemplo 1</a></p>
<p class="link"><a href="http://example2.com" class="sister" id="link2">Ejemplo 2</a></p>
<p class="link"><a href="http://example3.com" class="sister" id="link3">Ejemplo 3</a></p>
</div>
<p>Esto es un parrafo después del div.</p>
</body>
"""
soup = BeautifulSoup(html_doc, 'html.parser')
# Navegar a través del árbol
div_tag = soup.div
div_contents = div_tag.contents
print(div_contents) # Imprimirá los hijos directos de la etiqueta 'div'
## ['\n', <p class="link"><a class="sister" href="http://example1.com" id="link1">Ejemplo 1</a></p>, '\n', <p class="link"><a class="sister" href="http://example2.com" id="link2">Ejemplo 2</a></p>, '\n', <p class="link"><a class="sister" href="http://example3.com" id="link3">Ejemplo 3</a></p>, '\n']
div_children = div_tag.children
for child in div_children:
print(child) # Imprimirá cada hijo de la etiqueta 'div'
##
##
## <p class="link"><a class="sister" href="http://example1.com" id="link1">Ejemplo 1</a></p>
##
##
## <p class="link"><a class="sister" href="http://example2.com" id="link2">Ejemplo 2</a></p>
##
##
## <p class="link"><a class="sister" href="http://example3.com" id="link3">Ejemplo 3</a></p>
div_parent = div_tag.parent
print(div_parent) # Imprimirá el padre de la etiqueta 'div', que es el cuerpo
## <body>
## <h1>El tutorial de BeautifulSoup</h1>
## <div class="links">
## <p class="link"><a class="sister" href="http://example1.com" id="link1">Ejemplo 1</a></p>
## <p class="link"><a class="sister" href="http://example2.com" id="link2">Ejemplo 2</a></p>
## <p class="link"><a class="sister" href="http://example3.com" id="link3">Ejemplo 3</a></p>
## </div>
## <p>Esto es un parrafo después del div.</p>
## </body>
div_next_sibling = div_tag.find_next_sibling()
print(div_next_sibling) # Imprimirá la etiqueta que sigue después del 'div', en este caso el <p>
## <p>Esto es un parrafo después del div.</p>
div_prev_sibling = div_tag.find_previous_sibling()
print(div_prev_sibling) # Imprimirá la etiqueta que está antes del 'div', en este caso el <h1>
## <h1>El tutorial de BeautifulSoup</h1>
Filtrando el árbol #
BeautifulSoup también permite filtros más complejos utilizando funciones. Por ejemplo, puedes buscar todas las etiquetas que tengan exactamente dos atributos:
def has_two_attributes(tag):
return len(tag.attrs) == 2
two_attributes_tags = soup.find_all(has_two_attributes)
for tag in two_attributes_tags:
print(tag)
Usando selectores CSS #
Puedes buscar elementos utilizando selectores CSS con el método .select()
. Por ejemplo, puedes encontrar todos los elementos que tengan una cierta clase:
for tag in soup.select('.link'):
print(tag)
## <p class="link"><a class="sister" href="http://example1.com" id="link1">Ejemplo 1</a></p>
## <p class="link"><a class="sister" href="http://example2.com" id="link2">Ejemplo 2</a></p>
## <p class="link"><a class="sister" href="http://example3.com" id="link3">Ejemplo 3</a></p>
Este código imprimirá todas las etiquetas que tengan “link” como clase.
Extrayendo todo el texto #
Si solo quieres obtener todo el texto visible en la página, puedes utilizar el método .get_text()
:
print(soup.get_text())
##
##
## El tutorial de BeautifulSoup
##
## Ejemplo 1
## Ejemplo 2
## Ejemplo 3
##
## Esto es un parrafo después del div.
Esto imprimirá todo el texto que no esté dentro de una etiqueta.
En general, BeautifulSoup es una biblioteca muy poderosa y flexible para analizar HTML y XML. Puede manejar documentos mal formados y ofrece formas sencillas y complejas de buscar y modificar el árbol de documentos. Recuerda consultar la documentación para descubrir más de lo que puedes hacer.
Manejo de documentos XML #
BeautifulSoup también puede parsear documentos XML. Para hacer esto, necesitarás la librería lxml
. Puedes instalarla con pip:
!pip install lxml
Después de instalar lxml
, puedes usar BeautifulSoup para parsear documentos XML de la misma manera que parseas HTML:
xml_doc = """
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>Light Belgian waffles covered with strawberries and whipped cream</description>
<calories>900</calories>
</food>
</breakfast_menu>
"""
soup = BeautifulSoup(xml_doc, 'lxml-xml')
print(soup.prettify())
## <?xml version="1.0" encoding="utf-8"?>
## <breakfast_menu>
## <food>
## <name>
## Belgian Waffles
## </name>
## <price>
## $5.95
## </price>
## <description>
## Two of our famous Belgian Waffles with plenty of real maple syrup
## </description>
## <calories>
## 650
## </calories>
## </food>
## <food>
## <name>
## Strawberry Belgian Waffles
## </name>
## <price>
## $7.95
## </price>
## <description>
## Light Belgian waffles covered with strawberries and whipped cream
## </description>
## <calories>
## 900
## </calories>
## </food>
## </breakfast_menu>
Este código parseará el documento XML y luego lo imprimirá con una buena indentación.