(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo extraer tablas de PDFs en ETL: paso a paso

João Barros 05 de November de 2026 4 min de lectura

Extraer tablas de PDFs es habitual cuando las fuentes de datos llegan en informes estáticos. Este tutorial muestra cómo extraer, limpiar y transformar tablas de PDFs a CSV/Parquet — útil para integrar en pipelines ETL y automatizar la ingesta de informes.

Requisitos previos

  • Python 3.8+ y bibliotecas: tabula-py, pandas, camelot (opcional), pyarrow.
  • Java instalado (necesario para tabula-py).
  • Un PDF con tablas de ejemplo (páginas con tablas regulares).
  • Editor de código y línea de comandos.

Paso 1: Entender el formato de la tabla en el PDF

Antes de codificar, abre el PDF y comprueba: ¿las tablas tienen líneas bien definidas (grid) o son tablas basadas en alineación de texto? Saber esto ayuda a elegir la biblioteca: tabula-py funciona bien para tablas con grid; camelot también es útil. Anota las páginas y las columnas esperadas.

Paso 2: Instalar dependencias

Instala las bibliotecas necesarias y confirma que Java está accesible. Usamos tabula-py + pandas en este ejemplo porque es sencillo y fiable para muchos PDFs tabulares.

pip install tabula-py pandas pyarrow
# (opcional) pip install camelot-py[cv]
# Asegúrate de que 'java -version' funciona en tu línea de comandos

Paso 3: Extraer tablas del PDF con tabula-py

Usa tabula-py para extraer todas las tablas de una página específica o de todo el documento. El output inicial será una lista de DataFrame pandas.

from tabula import read_pdf
import pandas as pd

pdf_path = 'relatorio_exemplo.pdf'
# Extrae todas las tablas del PDF (pages='all' o número específico)
tables = read_pdf(pdf_path, pages='all', multiple_tables=True)
print(f'Tabelas extraídas: {len(tables)}')

Paso 4: Inspeccionar y limpiar cada tabla

Comprueba el contenido de cada DataFrame: columnas desordenadas, encabezados duplicados, filas de totales. Haz limpieza estándar: normalizar nombres de columnas, eliminar filas vacías y convertir tipos.

def clean_table(df: pd.DataFrame) -> pd.DataFrame:
    # Elimina filas totalmente vacías
    df = df.dropna(how='all')
    # Promueve la primera fila a encabezado si detecta encabezado incorrecto
    if df.columns.tolist() == list(range(len(df.columns))):
        df.columns = df.iloc[0].astype(str).str.strip()
        df = df[1:]
    # Trim en columnas de texto
    df = df.applymap(lambda x: x.strip() if isinstance(x, str) else x)
    # Ejemplo: convertir columna 'Valor' a float
    if 'Valor' in df.columns:
        df['Valor'] = (df['Valor']
                        .astype(str)
                        .str.replace('\u00A0', '')
                        .str.replace(',', '.')
                        .str.replace('[^0-9.\-]', '', regex=True))
        df['Valor'] = pd.to_numeric(df['Valor'], errors='coerce')
    return df.reset_index(drop=True)

cleaned_tables = [clean_table(t) for t in tables]

Paso 5: Conciliar tablas y estandarizar esquema

Si el PDF tiene tablas por página con el mismo esquema, combínalas. Si los esquemas difieren, mapea columnas a un esquema canónico para el ETL.

# Ejemplo: concatenar tablas con las mismas columnas
combined = pd.concat(cleaned_tables, ignore_index=True, sort=False)
# Seleccionar y renombrar para esquema canónico
canonical_cols = {'Data':'date', 'Descrição':'description', 'Valor':'amount'}
combined = combined.rename(columns=canonical_cols)
combined = combined[['date','description','amount']]

Paso 6: Validar y tratar errores comunes

Errores comunes: tablas no detectadas, columnas partidas, números con separadores locales. Registra excepciones, valida tipos y filas clave, y crea fallback (por ejemplo, intentar camelot si tabula falla).

# Validaciones simples
if combined.empty:
    raise ValueError('Nenhuma linha válida extraída do PDF')
# Ejemplos de checks
if combined['amount'].isna().sum() > 0:
    print('Atenção: valores sem conversão encontrados')

Paso 7: Exportar a CSV o Parquet para pipeline ETL

Guarda el resultado en un formato eficiente para consumo por las etapas siguientes del ETL: CSV para compatibilidad, Parquet para rendimiento en Big Data.

combined.to_csv('relatorio_tabelas.csv', index=False)
combined.to_parquet('relatorio_tabelas.parquet', index=False)

Verificar el resultado

Abre el CSV/Parquet producido y confirma: número de filas esperado, columnas correctas, tipos (date, amount). Haz una muestra y compara con el PDF original para asegurar que los valores coinciden. Revisa también los logs de advertencias para filas que fallaron en la conversión.

Conclusión

Al extraer tablas de PDFs en ETL puedes automatizar la ingesta de informes y preparar datos para análisis. Próximos pasos: integrar este script en un job programado, añadir tests unitarios y crear retries/fallback para PDFs problemáticos. Consejo: cuando una biblioteca falla en una página, intenta alternar entre tabula-py y camelot para obtener mejores resultados.