Introducción
El lenguaje de marcado de hipertexto (HTML) es el lenguaje de marcado estándar para crear páginas web. Podemos renderizar datos tabulares usando HTML <table>
elemento. La biblioteca de análisis de datos de Pandas proporciona funciones como read_html()
y to_html()
para que podamos importar y exportar datos a DataFrames.
En este artículo, aprenderemos cómo leer datos tabulares de un archivo HTML y cargarlos en un Pandas DataFrame. También aprenderemos a escribir datos desde un Pandas DataFrame y en un archivo HTML.
Nota: En este artículo, leeremos y escribiremos HTML <table>
elementos. Este artículo no incluye el análisis de todo el archivo HTML.
Leyendo HTML
Podemos leer tablas de un archivo HTML usando el read_html()
función. Esta función lee tablas de archivos HTML como Pandas DataFrames. Puede leer desde un archivo o una URL.
Echemos un vistazo a cada fuente de entrada una por una.
Leer datos HTML desde un archivo
Para esta sección, usaremos un conjunto de datos de entrada. Una tabla contiene lenguajes de programación y el año de su creación. La otra tabla tiene tamaños de terreno y su costo en USD.
Guarde el siguiente contenido HTML en un archivo llamado table_data.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Table Data</title>
</head>
<body>
<table>
<thead>
<tr>
<th>Programming Language</th>
<th>Creator</th>
<th>Year</th>
</tr>
</thead>
<tbody>
<tr>
<td>C</td>
<td>Dennis Ritchie</td>
<td>1972</td>
</tr>
<tr>
<td>Python</td>
<td>Guido Van Rossum</td>
<td>1989</td>
</tr>
<tr>
<td>Ruby</td>
<td>Yukihiro Matsumoto</td>
<td>1995</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>
Area (sq.ft)
</th>
<th>
Price (USD)
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
12000
</td>
<td>
500
</td>
</tr>
<tr>
<td>
32000
</td>
<td>
700
</td>
</tr>
</tbody>
</table>
</body>
</html>
Pandas necesita ayuda de otra biblioteca, llamada lxml
para analizar archivos HTML y XML. Para el read_html()
función para trabajar necesitas instalar lxml
:
$ pip install lxml
Una vez lmxl
está instalado, podemos usar el read_html()
función. Devuelve una lista de DataFrames, donde cada DataFrame es un elemento de tabla completo del archivo HTML dado. Accedemos a cada tabla como un DataFrame indexando la lista.
El siguiente código demuestra el uso de read_html()
función para leer tablas desde un archivo HTML:
import pandas as pd
tables = pd.read_html('table_data.html')
print('Tables found:', len(tables))
df1 = tables[0] # Save first table in variable df1
df2 = tables[1] # Saving next table in variable df2
print('First Table')
print(df1)
print('Another Table')
print(df2)
Nota: Mientras necesites lxml
instalado, no es necesario importarlo en su programa para que Pandas funcione.
Ejecutar el código anterior en un intérprete de Python producirá el siguiente resultado:
Tables found: 2
First Table
Programming Language Creator Year
0 C Dennis Ritchie 1972
1 Python Guido Van Rossum 1989
2 Ruby Yukihiro Matsumoto 1995
Another Table
Area (sq.ft) Price (USD)
0 12000 500
1 32000 700
Leyendo datos HTML desde URL
Así como leemos elementos de tabla de un archivo HTML, también podemos leer elementos de tabla de una página web HTML en un DataFrame con read_html()
. Sin embargo, en lugar del nombre del archivo, proporcionaremos una URL como esta:
read_html('https://en.wikipedia.org/wiki/Python_(programming_language)')
Y devolverá una lista de DataFrames donde cada DataFrame representa un elemento de tabla de la URL dada.
Aquí hay un código de ejemplo para leer elementos de tabla desde la URL de un sitio web usando Pandas:
import pandas as pd
tables = pd.read_html('https://en.wikipedia.org/wiki/Python_(programming_language)')
print('Tables found:', len(tables))
df1 = tables[0] # Save first table in variable df1
print('First Table')
print(df1.head()) # To print first 5 rows
Si ejecutamos con éxito el código anterior, podemos ver el resultado como:
Tables found: 10
First Table
0 1
0 NaN NaN
1 Paradigm Multi-paradigm: functional, imperative, object...
2 Designed by Guido van Rossum
3 Developer Python Software Foundation
4 First appeared 1991; 29 years ago[1]
Lectura de datos HTML de una URL que requiere autenticación
Sabemos que podemos leer elementos de tabla de un sitio web. Sin embargo, cuando el sitio requiere autenticación, el código se encuentra con la siguiente excepción:
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 401: UNAUTHORIZED
Para leer datos de dichas URL, usaremos el requests
módulo. Puedes instalarlo con pip
:
$ pip install requests
Ahora, usaremos el get()
método del requests
biblioteca para realizar una solicitud a la URL de un sitio web mientras proporciona la opción auth
parámetro si el sitio requiere autenticación.
Este método devuelve un objeto de respuesta de la página web. Podemos verificar el código de estado (para asegurarnos de que el contenido esté definitivamente allí) y obtener el texto del objeto de respuesta, y luego convertir la tabla en un DataFrame.
Veamos un ejemplo de uso requests
para obtener datos que requieran autenticación. Para este propósito, estamos utilizando https://httpbin.org:
import requests
r = requests.get('https://httpbin.org/basic-auth/john/johnspassword', auth=('john', 'johnspassword'))
print(r.status_code)
print(r.text)
Al ejecutar el código anterior, podemos ver el siguiente resultado:
200
{
"authenticated": true,
"user": "john"
}
Esto muestra que accedimos con éxito al contenido de la página web de una URL autenticada. Sin embargo, este sitio web solo contiene datos JSON y necesitamos elementos de tabla HTML como DataFrames.
Sigamos con la URL anterior y usemos requests
para leer tablas HTML como DataFrames. Si bien el sitio anterior era público, los pasos para acceder al contenido autenticado son los mismos.
Una vez que obtengamos una respuesta, podemos pasar el r.text
a read_html()
método. Y, como de costumbre, obtendremos una lista de tablas que contiene como DataFrames:
import pandas as pd
import requests
# Can use auth parameter for authenticated URLs
r = requests.get('https://en.wikipedia.org/wiki/Python_(programming_language)',
auth=('john', 'johnspassword'))
tables = pd.read_html(r.text)
print('Tables found:', len(tables))
df1 = tables[0]
print('First Table')
print(df1.head())
La ejecución de este código generará la siguiente salida:
Tables found: 10
First Table
0 1
0 NaN NaN
1 Paradigm Multi-paradigm: functional, imperative, object...
2 Designed by Guido van Rossum
3 Developer Python Software Foundation
4 First appeared 1991; 29 years ago[1]
Escribir tablas HTML con Pandas de Python
Hemos leído correctamente los datos de las tablas HTML. Escribamos Pandas DataFrame en un archivo HTML. Esto se puede lograr utilizando el to_html()
método.
los to_html()
toma la ruta del archivo al que desea exportar los datos. Si no proporciona una ruta absoluta, guardará un archivo relativo al directorio actual.
Puede exportar un DataFrame a una tabla HTML como esta:
import pandas as pd
df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df.to_html('write_html.html')
Este código producirá el siguiente archivo write_html.html
en el directorio actual:
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>A</th>
<th>B</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>1</td>
<td>3</td>
</tr>
<tr>
<th>1</th>
<td>2</td>
<td>4</td>
</tr>
</tbody>
</table>
Tenga en cuenta que la exportación no es un documento HTML completo, sino solo la tabla HTML en sí.
Escribir tablas HTML con estilo con Pandas de Python
Como podemos ver, por defecto el borde de la tabla es 1, la alineación es correcta y también tiene índices de DataFrame en <th>
etiquetas. Podemos cambiar esta estructura predeterminada proporcionando algunos parámetros opcionales.
Ocultar índice
Si no queremos incluir el índice en la salida de la tabla, podemos establecer index=False
en el to_html()
:
import pandas as pd
df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df.to_html('write_html.html', index=False)
Este código produce write_html.html
archivo con el siguiente contenido:
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th>A</th>
<th>B</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>3</td>
</tr>
<tr>
<td>2</td>
<td>4</td>
</tr>
</tbody>
</table>
Cambiar el borde de la mesa
El borde de la tabla predeterminado es de 1 píxel. Para cambiar este valor predeterminado, podemos configurar el border
parámetro a un valor en píxeles.
El siguiente código cambia el borde a 3 píxeles:
import pandas as pd
df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df.to_html('write_html.html', border=3)
El archivo generado ahora establece el atributo de borde de la tabla en «3»:
<table border="3" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>A</th>
<th>B</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>1</td>
<td>3</td>
</tr>
<tr>
<th>1</th>
<td>2</td>
<td>4</td>
</tr>
</tbody>
</table>
Justifica el texto
De forma predeterminada, el texto del encabezado de la tabla está alineado a la derecha. Cambiamos esta alineación con el justify
parámetro. Por ejemplo, haciendo justify="center"
agregará style="text-align: center;"
en el <tr>
etiqueta de la <thead>
etiqueta.
Intentemos alinear el texto del encabezado al centro y veamos los resultados:
import pandas as pd
df = pd.DataFrame({'A': [1, 'AAA'], 'B': ['BBB', 4]})
df.to_html('write_html.html', justify='center')
La tabla creada por el código anterior se ve así:
<table border="1" class="dataframe">
<thead>
<tr style="text-align: center;">
<th></th>
<th>A</th>
<th>B</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>1</td>
<td>BBB</td>
</tr>
<tr>
<th>1</th>
<td>AAA</td>
<td>4</td>
</tr>
</tbody>
</table>
El texto del encabezado de la tabla ahora está bellamente alineado con el centro.
Conclusión
En este tutorial, hemos aprendido cómo importar y exportar datos de tablas HTML con Pandas DataFrames. Cargamos datos de tablas HTML desde archivos, así como desde URL de páginas web. En el caso de las URL autenticadas, usamos el módulo de solicitudes para autenticar y recuperar los datos del sitio, y luego pasar el texto de respuesta al read_html()
función.
También hemos escrito un Pandas DataFrame como un archivo HTML usando el to_html()
función. Luego diseñamos la tabla generada pasando algunos parámetros opcionales como index
, border
y justify
. Esto facilita la escritura de los datos de DataFrame de manera presentacional.