Web scraping básico con Python y BeautifulSoup
Cómo extraer datos de una página web con requests y BeautifulSoup: descargar el HTML, encontrar los elementos y sacar el texto. Con las buenas prácticas para no romper nada ni que te bloqueen.
El web scraping es extraer datos de páginas web de forma automática: precios, titulares, listados, cualquier información que esté en una web pero no en un archivo descargable. Con Python son dos librerías y unas pocas líneas. Aquí lo básico bien hecho, incluyendo las prácticas que evitan que te bloqueen.
pip install requests beautifulsoup4
requests descarga la página; beautifulsoup4 (que se importa como bs4) analiza el HTML y te deja buscar dentro.
Descargar y analizar una página
import requests
from bs4 import BeautifulSoup
url = "https://ejemplo.com/articulos"
respuesta = requests.get(url)
respuesta.raise_for_status() # avisa si la página falló
sopa = BeautifulSoup(respuesta.text, "html.parser")
El raise_for_status() es importante: si la página devuelve un error (404, 500, etc.), te avisa de inmediato en vez de dejarte procesar HTML vacío y volverte loco buscando por qué no encuentras nada.
Encontrar elementos
BeautifulSoup busca por etiqueta, clase o id. Los métodos principales:
# Un solo elemento (el primero que encuentre)
titulo = sopa.find("h1")
print(titulo.text)
# Todos los elementos de un tipo
enlaces = sopa.find_all("a")
for enlace in enlaces:
print(enlace.text, "->", enlace.get("href"))
# Por clase CSS
articulos = sopa.find_all("div", class_="articulo")
# Por id
cabecera = sopa.find(id="cabecera")
Fíjate en class_ con guion bajo: se escribe así porque class es una palabra reservada de Python. Es un detalle que confunde a todos la primera vez.
Y .text saca el contenido de texto del elemento, mientras .get("href") saca el valor de un atributo (aquí, la dirección del enlace).
Un ejemplo real: extraer una lista
Digamos que quieres los títulos y enlaces de una lista de artículos:
import requests
from bs4 import BeautifulSoup
url = "https://ejemplo.com/blog"
respuesta = requests.get(url)
respuesta.raise_for_status()
sopa = BeautifulSoup(respuesta.text, "html.parser")
articulos = sopa.find_all("article", class_="post")
for articulo in articulos:
titulo = articulo.find("h2")
enlace = articulo.find("a")
if titulo and enlace: # comprobar que existen
print(titulo.text.strip(), "->", enlace.get("href"))
El if titulo and enlace es clave: no todos los elementos tendrán siempre lo que buscas, y si intentas .text sobre un resultado que fue None, obtienes el error 'NoneType' object has no attribute 'text'. Comprobar antes de acceder evita que el script reviente a mitad de camino. Y .strip() limpia los espacios y saltos de línea que el HTML suele arrastrar.
Las buenas prácticas que evitan bloqueos
Aquí lo que separa un scraper responsable de uno que acaba bloqueado. Primero, identifícate con un User-Agent, porque muchos sitios rechazan las peticiones sin él:
cabeceras = {"User-Agent": "Mozilla/5.0 (mi-script de datos)"}
respuesta = requests.get(url, headers=cabeceras)
Segundo, si vas a pedir varias páginas, espera entre una y otra. Bombardear un servidor con cientos de peticiones seguidas es la forma más rápida de que te bloqueen la IP, y además es de mala educación:
import time
for pagina in range(1, 6):
respuesta = requests.get(f"{url}?page={pagina}", headers=cabeceras)
# ...procesar...
time.sleep(2) # dos segundos entre peticiones
Tercero, y esto es tanto ético como legal: revisa el archivo robots.txt del sitio (por ejemplo ejemplo.com/robots.txt) para ver qué permiten rastrear, y respeta los términos de uso. Hacer scraping de datos públicos para uso personal suele estar bien; revender datos ajenos o saturar un servidor no. El scraping responsable te mantiene fuera de problemas.
Con esto puedes extraer datos de casi cualquier página estática. Para sitios que cargan su contenido con JavaScript después (donde el HTML inicial viene vacío) hará falta otra herramienta como Selenium o Playwright, pero eso es tema de otro artículo.
¿La página que quieres raspar carga con JavaScript, o necesitas guardar los datos en Excel o base de datos? Escríbeme desde contacto y lo vemos.