Análisis de Contenido HTML con BeautifulSoup
Al trabajar con datos web, a menudo te encontrarás con respuestas HTML. Para analizar HTML, la biblioteca BeautifulSoup de Python es una herramienta excelente. En este paso, aprenderemos a extraer información de las respuestas HTML.
Instalación de BeautifulSoup
Primero, instalemos BeautifulSoup y su analizador HTML:
pip install beautifulsoup4
Análisis HTML Básico
Creemos un archivo llamado parse_html.py para obtener y analizar una página web:
import requests
from bs4 import BeautifulSoup
## Realiza una petición a una página web
url = "https://www.example.com"
response = requests.get(url)
## Verifica si la petición fue exitosa
if response.status_code == 200:
## Analiza el contenido HTML
soup = BeautifulSoup(response.text, 'html.parser')
## Extrae el título de la página
title = soup.title.text
print(f"Título de la página: {title}")
## Extrae todos los párrafos
paragraphs = soup.find_all('p')
print(f"\nNúmero de párrafos: {len(paragraphs)}")
## Imprime el texto del primer párrafo
if paragraphs:
print(f"\nTexto del primer párrafo: {paragraphs[0].text.strip()}")
## Extrae todos los enlaces
links = soup.find_all('a')
print(f"\nNúmero de enlaces: {len(links)}")
## Imprime el atributo href del primer enlace
if links:
print(f"Href del primer enlace: {links[0].get('href')}")
else:
print(f"La petición falló con el código de estado: {response.status_code}")
Ejecuta este script para ver cómo extraer información básica de una página HTML:
python parse_html.py
Deberías ver una salida que muestra el título de la página, el número de párrafos, el texto del primer párrafo, el número de enlaces y la URL del primer enlace.
Encontrar Elementos Específicos
Ahora veamos cómo encontrar elementos específicos usando selectores CSS. Crea un archivo llamado html_selectors.py:
import requests
from bs4 import BeautifulSoup
## Realiza una petición a una página web con una estructura más compleja
url = "https://quotes.toscrape.com/"
response = requests.get(url)
## Verifica si la petición fue exitosa
if response.status_code == 200:
## Analiza el contenido HTML
soup = BeautifulSoup(response.text, 'html.parser')
## Encuentra todos los elementos de cita
quote_elements = soup.select('.quote')
print(f"Número de citas encontradas: {len(quote_elements)}")
## Procesa las primeras 3 citas
print("\nPrimeras 3 citas:")
for i, quote_element in enumerate(quote_elements[:3], 1):
## Extrae el texto de la cita
text = quote_element.select_one('.text').text
## Extrae el autor
author = quote_element.select_one('.author').text
## Extrae las etiquetas
tags = [tag.text for tag in quote_element.select('.tag')]
## Imprime la información
print(f"\nCita #{i}")
print(f"Texto: {text}")
print(f"Autor: {author}")
print(f"Etiquetas: {', '.join(tags)}")
else:
print(f"La petición falló con el código de estado: {response.status_code}")
Ejecuta este script para ver cómo usar selectores CSS para extraer elementos específicos:
python html_selectors.py
Deberías ver una salida que muestra información sobre las primeras tres citas, incluyendo el texto de la cita, el autor y las etiquetas.
Construyendo un Rascador Web Simple
Juntemos todo para construir un rascador web simple que extrae datos estructurados de una página web. Crea un archivo llamado quotes_scraper.py:
import requests
from bs4 import BeautifulSoup
import json
import os
def scrape_quotes_page(url):
## Realiza una petición a la página web
response = requests.get(url)
## Verifica si la petición fue exitosa
if response.status_code != 200:
print(f"La petición falló con el código de estado: {response.status_code}")
return None
## Analiza el contenido HTML
soup = BeautifulSoup(response.text, 'html.parser')
## Extrae todas las citas
quotes = []
for quote_element in soup.select('.quote'):
## Extrae el texto de la cita
text = quote_element.select_one('.text').text.strip('"')
## Extrae el autor
author = quote_element.select_one('.author').text
## Extrae las etiquetas
tags = [tag.text for tag in quote_element.select('.tag')]
## Añade la cita a nuestra lista
quotes.append({
'text': text,
'author': author,
'tags': tags
})
## Verifica si hay una página siguiente
next_page = soup.select_one('.next a')
next_page_url = None
if next_page:
next_page_url = 'https://quotes.toscrape.com' + next_page['href']
return {
'quotes': quotes,
'next_page': next_page_url
}
## Raspa la primera página
result = scrape_quotes_page('https://quotes.toscrape.com/')
if result:
## Imprime información sobre las citas encontradas
quotes = result['quotes']
print(f"Encontradas {len(quotes)} citas en la primera página")
## Imprime las primeras 2 citas
print("\nPrimeras 2 citas:")
for i, quote in enumerate(quotes[:2], 1):
print(f"\nCita #{i}")
print(f"Texto: {quote['text']}")
print(f"Autor: {quote['author']}")
print(f"Etiquetas: {', '.join(quote['tags'])}")
## Guarda las citas en un archivo JSON
output_dir = '/home/labex/project'
with open(os.path.join(output_dir, 'quotes.json'), 'w') as f:
json.dump(quotes, f, indent=2)
print(f"\nGuardadas {len(quotes)} citas en {output_dir}/quotes.json")
## Imprime información sobre la página siguiente
if result['next_page']:
print(f"\nURL de la página siguiente: {result['next_page']}")
else:
print("\nNo hay página siguiente disponible")
Ejecuta este script para raspar citas de un sitio web:
python quotes_scraper.py
Deberías ver una salida que muestra información sobre las citas encontradas en la primera página, y las citas se guardarán en un archivo JSON llamado quotes.json.
Revisa el archivo JSON para ver los datos estructurados:
cat quotes.json
El archivo debería contener un array JSON de objetos de cita, cada uno con propiedades de texto, autor y etiquetas.