Encontraste el dataset perfecto. Está ahí mismo en una página web, prolijamente formateado en una tabla HTML. Solo necesitas cargarlo en Pandas.
¿Qué tan difícil puede ser?
El One-Liner (Cuando Funciona)
Pandas tiene una función nativa para esto:
import pandas as pd
tables = pd.read_html('https://ejemplo.com/pagina-con-tabla')
df = tables[0] # Primera tabla de la página
Esto es hermoso cuando funciona. Tres líneas, listo.
Pero aquí va lo que los tutoriales no te dicen: pd.read_html() falla en una cantidad sorprendente de sitios web reales.
¿Tablas renderizadas por JavaScript? Pandas no las ve. Solo lee el HTML crudo.
¿Tablas que requieren autenticación? Vas a necesitar manejar sesiones y cookies primero.
¿Estructuras anidadas complejas? El parsing puede producir basura.
¿Medidas anti-scraping? Te van a bloquear o te van a servir contenido diferente.
Para tablas HTML simples y estáticas en páginas públicas, pd.read_html() es genial. Para todo lo demás, necesitas alternativas.
El Enfoque Requests + BeautifulSoup
Cuando pd.read_html() falla, el siguiente paso suele ser:
import requests
from bs4 import BeautifulSoup
import pandas as pd
response = requests.get('https://ejemplo.com/pagina')
soup = BeautifulSoup(response.content, 'html.parser')
table = soup.find('table', {'class': 'data-table'})
# Extraer headers
headers = [th.text.strip() for th in table.find_all('th')]
# Extraer filas
rows = []
for tr in table.find_all('tr')[1:]:
row = [td.text.strip() for td in tr.find_all('td')]
if row:
rows.append(row)
df = pd.DataFrame(rows, columns=headers)
Esto te da más control. Puedes apuntar a tablas específicas, manejar casos de borde, limpiar datos durante la extracción.
Las desventajas:
- Más código para escribir y mantener
- Sigue sin poder manejar contenido renderizado por JavaScript
- Se rompe cuando cambia la estructura del sitio
La Opción Nuclear: Selenium
Para sitios pesados en JavaScript:
from selenium import webdriver
from selenium.webdriver.common.by import By
import pandas as pd
driver = webdriver.Chrome()
driver.get('https://ejemplo.com/pagina')
# Esperar a que JavaScript renderice
import time
time.sleep(3)
# Ahora parsear el HTML renderizado
table = driver.find_element(By.CSS_SELECTOR, 'table.data-table')
# ... lógica de extracción similar a BeautifulSoup
driver.quit()
Esto funciona en casi todo. El navegador renderiza la página completamente, JavaScript incluido, y después extraes los datos.
El costo:
- Lento (segundos por página en vez de milisegundos)
- Requiere configuración de driver del navegador
- Intensivo en recursos
- Se siente excesivo para tomar una sola tabla
La Forma Práctica (Mi Favorita)
Esto es lo que realmente hago la mayoría de las veces:
- Abro la página en mi navegador
- Exporto la tabla a CSV con una extensión del navegador
- La cargo en Pandas:
df = pd.read_csv('tabla_exportada.csv')
Listo. Sin código de scraping. Sin depurar selectores HTML. Sin manejar casos de borde en Python.
El navegador ya renderizó el JavaScript. La extensión del navegador maneja el parsing HTML y la limpieza de datos. Obtengo un archivo CSV limpio que Pandas lee sin problemas.
Yo uso HTML Table Exporter para esto: detecta tablas automáticamente y exporta a CSV, JSON o Excel con un clic. Corre localmente, sin datos subidos a ningún lado.
Para una comparación más amplia de herramientas de exportación de tablas, mira nuestra guía de las mejores extensiones de Chrome para exportar tablas.
Pero hay otras herramientas también. El punto es: a veces el camino más rápido a un DataFrame no es a través de Python.
Cuándo Usar Qué
Este es mi árbol de decisión:
Usa pd.read_html() cuando:
- Tabla HTML estática simple
- Página pública, sin autenticación
- Necesitas automatizar extracciones repetidas
Usa BeautifulSoup cuando:
-
pd.read_html()falla - Necesitas control preciso sobre la extracción
- La estructura de la tabla es inusual
Usa Selenium cuando:
- JavaScript renderiza la tabla
- Necesitas interactuar con la página primero
- Se requiere automatización
Usa exportación por navegador cuando:
- Captura de datos puntual
- Página compleja que sería dolorosa de scrapear
- Quieres los datos en 30 segundos, no en 30 minutos
Un Ejemplo Práctico
Supongamos que quieres datos de PIB del Banco Mundial que se muestran en una tabla en su sitio.
El enfoque con pd.read_html():
import pandas as pd
url = 'https://data.worldbank.org/indicator/NY.GDP.MKTP.CD'
tables = pd.read_html(url)
# Rezar para que haya funcionado y descubrir qué índice de tabla necesitas
for i, table in enumerate(tables):
print(f"Tabla {i}: {table.shape}")
A veces funciona. A veces la tabla se carga vía JavaScript y no obtienes nada útil.
El enfoque por exportación del navegador:
- Abres la página
- Clic en el botón de exportar de tu extensión
- Eliges CSV
df = pd.read_csv('pib_banco_mundial.csv')
Tiempo total: unos 30 segundos.
Antes sentía que esto era "hacer trampa"—los verdaderos ingenieros de datos escriben scrapers, ¿no? Pero después me di cuenta de que obtener los datos rápida y precisamente es el verdadero objetivo. El método es solo un medio para un fin.
La Conclusión
pd.read_html() está subestimado para casos simples. La exportación por navegador está subestimada para casos complejos. Y escribir un scraper custom debería ser tu último recurso, no tu primer instinto.
Ajusta la herramienta al trabajo. Tu tiempo vale más que demostrar que puedes parsear HTML en Python.
Conoce más sobre HTML Table Exporter o pruébala gratis en la Chrome Web Store. ¿Cuál es tu método favorito para tomar tablas web? Cuéntame en los comentarios.
Top comments (0)