Leer y escribir tablas HTML con Pandas

    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.

     

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *