Pandas leer tablas HTML
de Pandaspd.read_html()La función puede analizar automáticamente los datos de tablas HTML de la página web y convertirlos en un DataFrame. Esto es muy útil en escenarios como extracción de datos web, análisis de precios de acciones, obtención de información financiera, etc.
Uso básico
read_html()La función busca y lee todos los elementos de tabla HTML en la página web, devolviendo una lista de DataFrames.
Leer una tabla individual
Ejemplo
# Leer todas las tablas de la página web
# Nota: requiere soporte de las bibliotecas lxml y beautifulsoup4
# pip install lxml beautifulsoup4
# Leer desde URL
tables = pd.read_html("https://example.com/table.html")
# Ver el número de tablas encontradas
print(f"Se encontraron {len(tables)} tablas")
# Obtener la primera tabla
df = tables[0]
print(df.head())
Leer múltiples tablas
Una página web puede contener múltiples tablas,read_html()devuelve una lista, a la que se puede acceder por índice:
Ejemplo
# Supongamos que la página web tiene varias tablas
tables = pd.read_html("https://example.com/data.html")
# Recorrer todas las tablas
for i, table in enumerate(tables):
print(f"\n"=== Tabla {i+1} ===")
print(f"Forma: {table.shape}")
print(table.head(3))
Explicación detallada de los parámetros comunes
| Parámetro | Descripción | Ejemplo |
|---|---|---|
io |
Fuente de entrada, puede ser una URL, ruta de archivo o cadena | "page.html" |
match |
Coincidencia regex, filtra tablas que contienen texto específico | match="销售额" |
header |
Especifica el índice de la fila de encabezado | header=0 |
attrs |
Filtra tablas mediante atributos HTML | attrs={"id": "table1"} |
skiprows |
Omite filas especificadas | skiprows=[0, 1] |
na_values |
Especifica cadenas que se tratan como valores faltantes | na_values=["N/A"] |
Filtrar tablas con el parámetro match
Ejemplo
# Usar el parámetro match para devolver solo tablas que contengan texto específico
# Por ejemplo: leer solo tablas que contengan "acciones"
tables = pd.read_html(
"https://example.com/finance.html",
match="acciones"
)
if tables:
df = tables[0]
print(df)
Ubicar tablas con precisión con el parámetro attrs
Ejemplo
# Ubicar la tabla mediante atributos HTML
# Por ejemplo: obtener la tabla con id="stock-table"
tables = pd.read_html(
"https://example.com/data.html",
attrs={"id": "stock-table"} # Buscar el elemento table con id="stock-table"
)
# O ubicar mediante class
tables = pd.read_html(
"https://example.com/data.html",
attrs={"class": "data-table"}
)
df = tables[0]
print(df)
Ejemplo práctico: extraer datos de acciones de páginas web
El siguiente ejemplo muestra cómo extraer datos de listas de acciones de sitios web financieros:
Ejemplo
from io import StringIO
# Crear un contenido HTML simulado para la demostración
# Al usarlo en la práctica, reemplazar con una URL real
html_content = '''
<table border="1">
<tr>
<th>Código de acción</th>
<th>Nombre de la acción</th>
<th>Precio de cierre</th>
<th>Cambio porcentual</th>
</tr>
<tr>
<td>600519</td>
<td>Kweichow Moutai</td>
<td>1850.00</td>
<td>2.35%</td>
</tr>
<tr>
<td>000858</td>
<td>Wuliangye</td>
<td>185.50</td>
<td>-1.20%</td>
</tr>
<tr>
<td>601318</td>
<td>Ping An de China</td>
<td>52.30</td>
<td>0.85%</td>
</tr>
</table>
'''
# Leer la tabla desde una cadena
tables = pd.read_html(StringIO(html_content))
df = tables[0]
print("Tabla original:")
print(df)
print()
# Limpieza de datos: procesar la columna de cambio porcentual
df["Cambio porcentual"] = df["Cambio porcentual"].str.replace("%", "").astype(float)
df["Precio de cierre"] = df["Precio de cierre"].astype(float)
print("Datos después de la limpieza:")
print(df)
La función de StringIO es: disfrazar una cadena como un objeto de archivo, de modo que pandas la procese siguiendo la lógica de lectura de flujos de archivo, en lugar de interpretarla erróneamente como una ruta o URL.
Salida:
原始表格:
股票代码 股票名称 收盘价 涨跌幅
0 600519 贵州茅台 1850.0 2.35%
1 858 五粮液 185.5 -1.20%
2 601318 中国平安 52.3 0.85%
清洗后的数据:
股票代码 股票名称 收盘价 涨跌幅
0 600519 贵州茅台 1850.0 2.35
1 858 五粮液 185.5 -1.20
2 601318 中国平安 52.3 0.85
Leer tablas de Wikipedia
Ejemplo
# Leer tablas de la página de Wikipedia
# Tomemos como ejemplo la lista de población por país
url = "https://en.wikipedia.org/wiki/List_of_countries_by_population_(United_Nations)"
try:
tables = pd.read_html(url)
print(f"La página tiene {len(tables)} tablas en total")
# Normalmente la primera tabla es la que necesitamos
df = tables[0]
print(df.head(10))
except Exception as e:
print(f"Error de lectura: {e}")
print("Asegúrese de instalar las bibliotecas necesarias: pip install lxml beautifulsoup4")
Limpieza y procesamiento de datos
Las tablas leídas de páginas web generalmente requieren una limpieza adicional antes de poder usarse para análisis.
Operaciones comunes de limpieza
Ejemplo
from io import StringIO
# Simular una tabla con varios tipos de datos sucios
html_content = '''
<table>
<tr><th>Fecha</th><th>Producto</th><th>Ventas</th><th>Notas</th></tr>
<tr><td>2024-01-01</td><td>Producto A</td><td>1,234</td><td>N/A</td></tr>
<tr><td>2024-01-02</td><td>Producto B</td><td>567</td><td>Agotado</td></tr>
<tr><td>2024-01-03</td><td>Producto C</td><td>--</td><td>Sin registrar</td></tr>
</table>
'''
df = pd.read_html(StringIO(html_content))[0]
print("Datos originales:")
print(df)
print()
# Pasos de limpieza
# 1. Renombrar columnas
df.columns = ["Fecha", "Producto", "Ventas", "Notas"]
# 2. Manejar valores faltantes
df = df.replace(["N/A", "--", "Sin registrar", "Agotado"], pd.NA)
# 3. Limpiar la columna numérica (eliminar comas)
df["Ventas"] = df["Ventas"].str.replace(",", "").replace(pd.NA, None)
df["Ventas"] = pd.to_numeric(df["Ventas"], errors="coerce")
# 4. Convertir fecha
df["Fecha"] = pd.to_datetime(df["Fecha"])
print("Después de la limpieza:")
print(df)
print("\nTipo de datos:)
print(df.dtypes)
Salida:
原始数据:
日期 产品 销量 备注
0 2024-01-01 产品A 1234 NaN
1 2024-01-02 产品B 567 缺货
2 2024-01-03 产品C -- 未统计
清洗后:
日期 产品 销量 备注
0 2024-01-01 产品A 1234.0 NaN
1 2024-01-02 产品B 567.0 <NA>
2 2024-01-03 产品C NaN <NA>
数据类型:
日期 datetime64[ns]
产品 object
销量 float64
备注 object
dtype: object
Precauciones y problemas comunes
1. Instalar bibliotecas de dependencias
read_html()Se necesitanlxmlybeautifulsoup4bibliotecas:
pip install lxml beautifulsoup4
2. Problemas de red
Al leer URLs de red, es posible encontrar latencia de red o restricciones de acceso. Se recomienda añadir una configuración de tiempo de espera adecuada o utilizar caché local.
3. Estructura de tabla compleja
Algunas tablas de páginas web usan estructuras complejas como celdas combinadas o tablas anidadas, lo que puede provocar fallos de análisis. En este caso, se puede intentar usar BeautifulSoup para analizar el HTML directamente.
4. Integridad de los datos
Los datos de las páginas web pueden cambiar en cualquier momento. Se recomienda verificar la integridad de los datos después de la lectura y compararlos con la fuente original.
Al extraer datos de páginas web, respete las reglas de robots.txt del sitio y las leyes y regulaciones correspondientes. No realice solicitudes con demasiada frecuencia para no sobrecargar el servidor.
Resumen
pd.read_html()Es una herramienta poderosa para extraer datos de tablas web, ya que puede convertir rápidamente tablas HTML en DataFrames. En uso real, se debe prestar atención a la instalación de bibliotecas de dependencias, problemas de red, limpieza de datos sucios, etc. Los datos extraídos generalmente requieren un procesamiento adicional para el análisis; se recomienda combinarlos con las funciones de limpieza de datos de Pandas.