Cómo descargar de forma dinámica una tabla HTML (indicando la URL) y cómo trabajar con los datos de la tabla usando Python y la librería pandas. Cómo hacer web scraping para obtener datos de una página web y formatear el resultado en tablas. Cómo quitar columnas, renombrar columnas, filtrar filas, ordenar, etc.

Instalar librería pandas, lxml y html5lib en Python con pip

En primer lugar instalaremos pandas, ejecutando desde una ventana de MS-DOS:

Instalar librería pandas,  lxml y html5lib en Python con pip

El comando:

pip install pandas
Instalar librería pandas,  lxml y html5lib en Python con pip

Para instalar lxml ejecutaremos el comando:

pip install lxml

Instalaremos también la librería html5lib, con el comando:

pip install html5lib

Analizar la página web HTML que contenga una o varias tablas

Antes de entrar en Python, como es lógico, deberemos saber desde qué URL (sitio web) queremos obtener una o varias tablas. Por ejemplo, supongamos que queremos obtener la tabla de caracteres ASCII y su correspondencia a decimal, que está en la URL:

Lo primero que haremos será visitar la URL y analizar las tablas que contiene. En el ejemplo queremos obtener la tabla que contiene el nombre del carácter y su valor decimal:

Analizar la página web HTML que contenga una o varias tablas

Podemos investigar más a fondo la tabla mostrando el código fuente de la página y viendo su código fuente de creación:

Analizar la página web HTML que contenga una o varias tablas

Buscaremos el texto «<table>» hasta posicionarnos en la tabla que nos interese. Así podemos comprobar, por ejemplo, su ID (si lo tiene) y su estructura HTML:

Analizar la página web HTML que contenga una o varias tablas

Esto no es estrictamente necesario para trabajar con pandas y Python, pero sí aconsejable para asegurarnos de que obtenemos la tabla que queremos, si hay varias en la misma URL.

Empezando con pandas en Python para obtener una tabla desde una página web online

Mostramos un ejemplo para obtener o bien la primera tabla de una URL y pasarla a un Dataframe, o bien obtener todas las tablas de una URL, y pasar a un Dataframe sólo la primera:

import pandas as pd

# Obtenemos la tabla de ejemplo de una página web
url = 'https://proyectoa.com/tabla-de-correspondencias-ascii-y-iso-8859-1/'
# Para obtener la primera tabla
tablaASCII = pd.read_html(url)[0]
# Estableceremos el Dataframe donde guardaremos la tabla
df = pd.DataFrame(tablaASCII)

# También podemos obtener todas las tablas de la URL en una variable
tablaASCII = pd.read_html(url)
# Y establecer un DataFrame con la primera tabla obtenida
df = pd.DataFrame(tablaASCII[0])

Para comprobar que se ha obtenido la información correctamente, podemos mostrar por pantalla parte del contenido de la tabla obtenida en el Dataframe, con:

print(df)

Obtendremos este resultado:

Empezando con pandas en Python para obtener una tabla desde una página web

Para obtener las columnas y el tipo de datos que le ha asignado pandas por defecto podemos usar:

print(df.dtypes)

En nuestro ejemplo nos mostrará:

Empezando con pandas en Python para obtener una tabla desde una página web

Que se corresponden con las 4 columnas de la tabla, de tipo «object» y con el nombre 0, 1, 2, 3.

También podemos obtener más información de la tabla, con:

print(df.info())

Que nos devolverá las columnas, el número de filas, el tamaño de memoria usado total, el tipo de datos y el número de filas no nulas de cada columna:

Empezando con pandas en Python para obtener una tabla desde una página web

Trabajar con la tabla obtenida, quitar columnas y filas, renombrar, filtrar, ordenar

Una vez obtenida la tabla en el Dataframe, podremos hacer cualquier cosa que necesitemos con ella.

Suprimir columnas de una tabla con pandas y Python

Como ejemplo vamos a quitar la columna 2 (que se corresponde con «Hex») y la columna 3 (que se corresponde con «Car.»), para ello, ejecutamos la siguiente línea:

df = df.drop(columns=[2, 3])

La línea anterior quitará del Dataframe df las columnas 2 y 3 y cambiará el Dataframe resultante por el mismo para que se actualicen los cambios. Si mostramos el Dataframe habrá quedado sin estas dos columnas:

Suprimir columnas de una tabla con pandas y Python

Como vemos, han quedado las columnas «Nombre» y «Dec» y se han quitado las columnas «Hex» y «Car.».

Suprimir filas en tabla con pandas y Python

También podemos eliminar filas por su índice, por ejemplo, para eliminar las filas 3, 5 y 6:

df = df.drop([3,5,6])

Si mostramos ahora la tabla, nos devolverá:

Acotar resultados, trabajar con subconjuntos de datos de la tabla principal con pandas y Python

Para acotar los resultados, para obtener un subconjunto del Dataframe completo, podemos usar:

df = df.loc[0:10]

El ejemplo anterior mostrará de la fila con ID 0 a la fila con ID 10, teniendo en cuenta que no aparecerán las quitadas anteriormente:

Acotar resultados, trabajar con subconjuntos de datos de la tabla principal con pandas y Python

Para mostrar las últimas cuatro filas de la tabla podemos usar:

df = df.loc[4:]

Ordenar registros por columna con pandas y Python

Podremos ordenar los resultados obtenidos. Por ejemplo, para ordenar de forma ascendente por la columna «Dec» (columna 1), usaremos la línea de código Python:

df.sort_values(df.columns[1], ascending=True)

Que mostrará los resultados obtenidos ordenados por la columna 1 de forma descendente:

Ordenar registros por columna con pandas y Python

Renombrar columnas de la tabla con pandas y Python

Para renombrar columnas en la tabla, por ejemplo, en nuestra tabla que tiene dos columnas, asignaremos a la primera el nombre «Caracter» y a la segunda el nombre «Valor_ASCII». Para ello ejecutaremos:

df = df.set_axis(['Caracter', 'Valor_ASCII'], axis=1)
Renombrar columnas de la tabla con pandas y Python

Establecer tipo de datos de una columna de una tabla con pandas y Python

Para cambiar el tipo de datos de una columna, por ejemplo, para establecer a entero (integer, int) la columna «Valor_ASCII») usaremos:

df = df.astype({"Valor_ASCII": int}, errors='raise')

Filtrar resultados de la tabla con pandas y Python

Para filtrar los resultados de la tabla obtenida online con pandas, podemos usar:

df = df.loc[(df['Valor_ASCII'] >= 3) & (df['Valor_ASCII'] <= 7)]

El ejemplo anterior filtrará los registros (filas) de la tabla y mostrará sólo las filas cuyo valor de columna «Valor_ASCII» sea mayor o igual que 3 y menos o igual que 7:

Filtrar resultados de la tabla con pandas y Python

Obtener y mostrar el valor de una fila y columna (celda) de la tabla con pandas y Python

Para obtener el valor de una fila/columna (celda) de la tabla, podemos usar:

valorASCII = df['Valor_ASCII'].values[0]
caracter = df['Caracter'].values[0]
print("{} -> {}".format(caracter, valorASCII))

Que devolverá el valor de la columna «Valor_ASCII» de la fila 0 (la primera):

Obtener y mostrar el valor de una fila y columna (celda) de la tabla con pandas y Python

Código fuente en Python completo del los ejemplos del artículo

El código fuente completo de todos los ejemplos de este artículo:

import pandas as pd

#  Obtenemos la tabla de ejemplo de una página web
#  Por ejemplo la tabla de correspondencias ASCII
url = 'https://proyectoa.com/tabla-de-correspondencias-ascii-y-iso-8859-1/'

#  Si conocemos el ID de la tabla, podremos obtener directamente esa tabla (viendo el código fuente de la URL)
#  Si la tabla tiene el ID y lo conocemos ejecutamos lo siguiente para obtener sólo esa tabla:
#tablaASCCI = pd.read_html(url, attrs = {'id':'id_de_la_tabla'})

#  En este ejemplo la tabla no tiene ID, pero sí sabemos que es la primera tabla que aparece
#  Para obtener la primera tabla ejecutamos:
#tablaASCII = pd.read_html(url)[0]

#  También podemos obtener todas las tablas de la URL en una variable
tablaASCII = pd.read_html(url)

#  Y establecer un DataFrame con la primera tabla obtenida
df = pd.DataFrame(tablaASCII[0])

#  Para depurar, mostramos parte de la información de la tabla obtenida
#print(df)

#  También podemos mostrar las columnas que ha obtenido pandas de la URL
#df.info()

#  Ahora que conocemos las columnas y filas obtenidas, quitamos las columnas que no queramos del DataFrame
#  Por ejemplo, quitaremos la columna 3 (Car.) y la 2 (Hex)
#  Podemos quitarlas por el nombre de la columna si se conoce o bien por la posición
#  Para quitarlas por el nombre
# df = df.drop(columns=['Hex', 'Car.'])
#  Para quitarlas por la posición
df = df.drop(columns=[2, 3])
#df.info()
#print(df)

#  Podemos eliminar filas, por índice:
df = df.drop([3,5,6])
#print(df)

#  Podemos aplicar filtros a los resultados
#  Por ejemplo mostrar de la fila con ID 0 a la ID 10 (teniendo en cuenta que no aparecerán las quitadas anteriormente)
df = df.loc[0:10]
#print(df)

#  Para mostrar las 4 últimas filas de las obtenidas anteriormente
df = df.loc[4:]
#print(df)

#  Para renombrar las columnas del Dataframe
df = df.set_axis(['Caracter', 'Valor_ASCII'], axis=1)

#  Para convertir a un tipo de datos una columna del Dataframe
#  Por ejemplo, para convertir la columna Valor_ASCII a int
df = df.astype({"Valor_ASCII": int}, errors='raise')

#  Podemos incluso hacer filtros por valores de celdas que cumplan una condición
#  Por ejemplo, mostrar de las 4 filas anteriores las que su valor numérico 
#  esté entre 3 y 7 de la columna "Valor_ASCII"
df = df.loc[(df['Valor_ASCII'] >= 3) & (df['Valor_ASCII'] <= 7)]
#print(df)

#  Podemos mostrar sólo el valor de una fila y columna, por ejemplo
valorASCII = df['Valor_ASCII'].values[0]
caracter = df['Caracter'].values[0]
print("{} -> {}".format(caracter, valorASCII))