domingo, 4 de octubre de 2026Finanzas personales claras para llegar a fin de mes

Leer facturas con Python: automatiza tus gastos

¿Cansado de teclear facturas a mano? Con Python puedes extraer los datos de tus PDF y XML, clasificarlos y tener un control real de tus gastos. Te contamos cómo empezar.

Close-up view of a computer screen displaying code in a software development environment.
Foto: Mathews Jumba / Pexels
Contenido del artículo
  1. Qué necesitas para empezar a leer facturas con Python
  2. Leer facturas en PDF: texto seleccionable vs. escaneado
  3. Extraer datos concretos: importe, fecha y proveedor
  4. Facturas en XML (Facturae): la vía más sencilla
  5. Usar OCR para facturas en papel o imágenes
  6. Clasificar y guardar los gastos automáticamente
  7. Errores comunes y cómo evitarlos
  8. Ejemplo práctico: de factura PDF a hoja de cálculo
  9. Nuestra recomendación final para automatizar tus facturas
  10. Preguntas frecuentes

Para leer facturas con Python puedes usar pdfplumber o PyPDF2 si el PDF tiene texto seleccionable, xml.etree.ElementTree si la factura viene en formato XML (Facturae) y pytesseract cuando solo tienes una imagen o un escaneo. Con unas pocas líneas extraes el texto, lo parseas con expresiones regulares y lo guardas en un CSV o un Excel. Así dejas de teclear importes cada mes.

La clave está en identificar primero qué tipo de factura tienes entre manos. No es lo mismo una factura de luz descargada del área de cliente de tu comercializadora (PDF con texto o XML estructurado) que una foto del ticket del fontanero. Cada formato tiene su herramienta, y elegir mal te hace perder horas.

En esta guía verás código real, patrones de regex útiles y un ejemplo completo desde un PDF hasta una hoja de cálculo. No necesitas ser programador: con saber abrir un editor y ejecutar un script vas sobrado.

En resumen:

  • PDF con texto → pdfplumber o PyPDF2; PDF escaneado → OCR con pytesseract.
  • XML Facturae → xml.etree.ElementTree, la vía más limpia y fiable.
  • Guarda todo con pandas en CSV o Excel y añade una columna de categoría.
  • Empieza con pocas facturas, ajusta los patrones y revisa siempre a mano lo dudoso.

Qué necesitas para empezar a leer facturas con Python

No hace falta un máster. Con saber qué es una variable, un bucle y una función vas más que sobrado para automatizar la lectura de facturas. Si nunca has tocado Python, dedica una tarde a un tutorial básico y vuelve.

Herramientas mínimas:

  • Python 3.10 o superior instalado en tu equipo.
  • Un editor de código: VS Code es gratuito y cómodo. También vale PyCharm Community o incluso el IDLE que viene con Python.
  • Google Colab si no quieres instalar nada: funciona en el navegador, es gratis y ya trae muchas librerías. Ideal para probar.

Librerías que vas a usar:

Librería Para qué sirve Instalación
pdfplumber Extraer texto y tablas de PDF con texto pip install pdfplumber
PyPDF2 Alternativa ligera para texto de PDF pip install PyPDF2
pandas Organizar datos y exportar a CSV/Excel pip install pandas
xml.etree.ElementTree Leer XML (Facturae) Ya viene con Python
pytesseract + Pillow OCR sobre imágenes y PDF escaneados pip install pytesseract Pillow
openpyxl Escribir archivos .xlsx pip install openpyxl

Para instalar todo de golpe:

pip install pdfplumber PyPDF2 pandas pytesseract Pillow openpyxl

Aviso importante: pytesseract necesita además el motor Tesseract OCR instalado en el sistema (no basta con el paquete de Python). En Windows se descarga el instalador oficial; en macOS, brew install tesseract; en Linux, sudo apt install tesseract-ocr. Si usas Colab, se instala con apt-get.

Y un aviso más: muchas facturas que recibes por email son PDF escaneados (una imagen metida en un PDF). Esas no se leen con pdfplumber, necesitan OCR. Lo vemos más abajo.

Leer facturas en PDF: texto seleccionable vs. escaneado

A laptop screen showing a code editor with visible programming code in a dimly lit environment.
Foto: Daniil Komov / Pexels

Antes de escribir una línea de código, haz la prueba del copia-pega: abre el PDF, intenta seleccionar el texto del importe y cópialo. Si se selecciona, tienes un PDF con texto. Si no, es una imagen escaneada.

PDF con texto: pdfplumber al rescate

import pdfplumber

with pdfplumber.open("factura_luz.pdf") as pdf:
    texto = ""
    for pagina in pdf.pages:
        texto += pagina.extract_text() or ""

print(texto[:500])  # ver un fragmento

pdfplumber también extrae tablas con pagina.extract_tables(), muy útil si la factura las usa para desglosar conceptos.

PDF escaneado: OCR con pytesseract

Aquí primero conviertes el PDF a imagen y luego aplicas OCR:

import pytesseract
from PIL import Image
from pdf2image import convert_from_path

paginas = convert_from_path("factura_escaneada.pdf", dpi=300)
for i, pagina in enumerate(paginas):
    texto = pytesseract.image_to_string(pagina, lang="spa")
    print(f"--- Página {i+1} ---")
    print(texto)

Necesitarás pdf2image (pip install pdf2image) y, en Windows, Poppler instalado. La precisión baja mucho si la imagen está torcida, borrosa o con sombras. Para facturas clave, revisa siempre el resultado.

Extraer datos concretos: importe, fecha y proveedor

Ya tienes el texto. Ahora hay que pescar los datos. Aquí entran las expresiones regulares con el módulo re.

Patrones que te servirán una y otra vez:

Dato Patrón regex Ejemplo que captura
Fecha \b(\d{2}/\d{2}/\d{4})\b 14/03/2026
Importe con € (\d{1,3}(?:\.\d{3})*,\d{2})\s?€ 1.234,56 €
Importe tras "Total" Total(?:\s+a\s+pagar)?[:\s]+([\d.,]+)\s?€ Total a pagar: 87,45 €
NIF/CIF \b([A-Z]\d{8})\b B12345678
IBAN \bES\d{22}\b ES9121000418450200051332

Ejemplo con una factura de luz:

import re

def extraer_datos(texto):
    datos = {}
    m = re.search(r"(\d{2}/\d{2}/\d{4})", texto)
    datos["fecha"] = m.group(1) if m else None

    m = re.search(r"Total(?:\s+a\s+pagar)?[:\s]+([\d.]+,\d{2})", texto, re.IGNORECASE)
    datos["importe"] = m.group(1) if m else None

    m = re.search(r"(Iberdrola|Endesa|Naturgy|Repsol|TotalEnergies)", texto, re.IGNORECASE)
    datos["proveedor"] = m.group(1) if m else None

    return datos

print(extraer_datos(texto))

Truco: prueba siempre con al menos tres facturas de la misma comercializadora. Los formatos cambian entre meses y entre compañías. Si tienes dudas sobre qué campos mirar, en nuestra guía sobre cómo leer la factura de la luz desglosamos cada apartado.

Facturas en XML (Facturae): la vía más sencilla

Close-up of hands typing on a laptop keyboard, Python book in sight, coding in progress.
Foto: Christina Morillo / Pexels

Si tu proveedor te envía factura electrónica en formato Facturae, enhorabuena: es el escenario más fácil. No hay OCR, no hay regex frágil. Los datos están etiquetados.

Un XML simplificado se ve así:

<Facturae>
  <FileHeader>
    <SellerParty>
      <TaxIdentification>
        <TaxIdentificationNumber>B12345678</TaxIdentificationNumber>
      </TaxIdentification>
      <LegalEntity>
        <CorporateName>Comercializadora Ejemplo S.L.</CorporateName>
      </LegalEntity>
    </SellerParty>
  </FileHeader>
  <Invoices>
    <Invoice>
      <InvoiceIssueData>
        <IssueDate>2026-03-14</IssueDate>
        <InvoiceTotal>87.45</InvoiceTotal>
      </InvoiceIssueData>
    </Invoice>
  </Invoices>
</Facturae>

Y así lo lees:

import xml.etree.ElementTree as ET

tree = ET.parse("factura.xml")
root = tree.getroot()

total = root.find(".//InvoiceTotal").text
fecha = root.find(".//IssueDate").text
emisor = root.find(".//CorporateName").text

print(emisor, fecha, total)

Ventaja enorme: no dependes de la posición del texto ni del OCR. Si trabajas con muchas facturas, pide siempre el XML al proveedor. Si quieres pasarlas directamente a Excel, tienes el paso a paso en pasar facturas XML a Excel. Y si quieres entender cada campo del estándar, lo desmenuzamos en cómo leer una factura XML (Facturae).

Aviso: las facturas de particulares (luz, agua, teléfono, internet) suelen llegar en PDF, no en XML. El XML Facturae es más habitual entre empresas.

Usar OCR para facturas en papel o imágenes

Tienes un ticket arrugado en el bolsillo o una factura que solo te dieron en papel. La solución: escanear a 300 ppp o hacer una foto con buena luz, sin sombras y lo más recta posible. Luego:

import pytesseract
from PIL import Image

imagen = Image.open("ticket.jpg")
texto = pytesseract.image_to_string(imagen, lang="spa")
print(texto)

Cosas que debes saber:

  • La precisión no es del 100 %. Confunde 0 con O, 1 con l, y a veces se come la coma decimal.
  • Cuanto mejor la imagen, mejor el resultado. Endereza, recorta y sube el contraste antes del OCR.
  • Para muchas facturas, pide factura electrónica. El OCR es un parche, no una solución industrial.

Alternativa: servicios en la nube como Google Vision o AWS Textract tienen OCR muy superior. Pero ojo con la privacidad: estás subiendo tus facturas (con tus datos fiscales y de consumo) a un tercero. Para cuatro facturas al año, el OCR local con Tesseract es más que suficiente. Si te interesa el enfoque con modelos de lenguaje, lo tratamos en leer facturas con IA.

Clasificar y guardar los gastos automáticamente

Con los datos extraídos, el siguiente paso es guardarlos ordenados. pandas es tu amigo.

import pandas as pd

categorias = {
    "Iberdrola": "Luz",
    "Endesa": "Luz",
    "Naturgy": "Gas",
    "Canal de Isabel II": "Agua",
    "Movistar": "Telefonía",
    "Vodafone": "Telefonía",
}

def categorizar(proveedor):
    if not proveedor:
        return "Otros"
    for clave, cat in categorias.items():
        if clave.lower() in proveedor.lower():
            return cat
    return "Otros"

registro = {
    "fecha": "14/03/2026",
    "proveedor": "Iberdrola",
    "importe": 87.45,
}
registro["categoria"] = categorizar(registro["proveedor"])

df = pd.DataFrame([registro])
df.to_csv("gastos.csv", index=False, mode="a", header=False)

Para Excel, cambia la última línea por df.to_excel("gastos.xlsx", index=False) (necesitas openpyxl). Con un diccionario de categorías como el de arriba, en pocos minutos clasificas cientos de facturas. Después puedes hacer una tabla dinámica por mes y categoría y ver dónde se te va el dinero.

Consejo: guarda también el nombre del archivo original en una columna. Si algo cuadra mal, sabrás qué factura revisar.

Errores comunes y cómo evitarlos

  • Formatos inconsistentes: la misma comercializadora cambia el diseño cada cierto tiempo. Solución: escribe regex flexibles y prueba con facturas de varios meses.
  • Acentos y caracteres raros: pdfplumber a veces devuelve ó en vez de ó. Normaliza con unicodedata o texto.encode("latin-1", "ignore").decode("utf-8") según el caso.
  • Importes con punto y coma mezclados: en España el separador decimal es la coma y el de miles el punto. Convierte siempre antes de sumar: float(valor.replace(".", "").replace(",", ".")).
  • Escaneos torcidos: endereza la imagen antes del OCR. Tesseract es muy sensible a la inclinación.
  • Confiar sin validar: comprueba que el importe extraído tiene sentido (por ejemplo, entre 0 y 500 € para una factura doméstica). Si sale 8.745 €, algo falló.
  • Creer que todo se puede automatizar: no. Hay facturas que siempre requerirán revisión humana.

Empieza con cinco facturas. Ajusta patrones, revisa resultados, y solo cuando funcione bien, lánzalo sobre todo el histórico.

Ejemplo práctico: de factura PDF a hoja de cálculo

Supón una factura de luz ficticia llamada factura_iberdrola_marzo.pdf con este texto:

Iberdrola Clientes S.A.U.
NIF: A95758389
Fecha de emisión: 14/03/2026
Periodo de facturación: 01/02/2026 - 28/02/2026
Consumo: 245 kWh
Total a pagar: 87,45 €

Script completo:

import pdfplumber
import re
import pandas as pd

ARCHIVO = "factura_iberdrola_marzo.pdf"

# 1. Extraer texto
with pdfplumber.open(ARCHIVO) as pdf:
    texto = "\n".join(p.extract_text() or "" for p in pdf.pages)

# 2. Extraer campos con regex
fecha = re.search(r"Fecha de emisión[:\s]+(\d{2}/\d{2}/\d{4})", texto)
importe = re.search(r"Total a pagar[:\s]+([\d.]+,\d{2})", texto)
proveedor = re.search(r"^(Iberdrola|Endesa|Naturgy|Repsol)", texto, re.MULTILINE)

fecha = fecha.group(1) if fecha else None
importe = float(importe.group(1).replace(".", "").replace(",", ".")) if importe else None
proveedor = proveedor.group(1) if proveedor else "Desconocido"

# 3. Categorizar
categorias = {"Iberdrola": "Luz", "Endesa": "Luz", "Naturgy": "Gas"}
categoria = categorias.get(proveedor, "Otros")

# 4. Guardar
df = pd.DataFrame([{
    "fecha": fecha,
    "proveedor": proveedor,
    "categoria": categoria,
    "importe": importe,
    "archivo": ARCHIVO,
}])
df.to_csv("gastos.csv", index=False, mode="a", header=False)
print(df)

Resultado:

fecha proveedor categoria importe archivo
14/03/2026 Iberdrola Luz 87.45 factura_iberdrola_marzo.pdf

Adapta los patrones a tus facturas reales: cambia el nombre del proveedor, ajusta la etiqueta "Total a pagar" por la que use tu comercializadora y añade campos si te interesan (consumo, periodo, NIF). Si tu proveedor te manda XML, mejor tira por esa vía: mira pasar facturas XML a Excel.

Nuestra recomendación final para automatizar tus facturas

Resumiendo: si tienes facturas XML, empieza por ahí, es lo más limpio. Si son PDF con texto, pdfplumber y expresiones regulares te resuelven el 90 % del trabajo. El OCR déjalo para casos puntuales: tickets de papel o facturas escaneadas que no puedes conseguir de otra forma.

Prueba primero en Google Colab, que no requiere instalar nada, y cuando el script funcione, pásalo a tu equipo. Itera con pocas facturas antes de lanzarlo sobre todo tu archivo.

Recuerda que esto no sustituye la revisión humana: sigue comprobando importes y fechas clave, sobre todo si vas a usar los datos para la declaración o para reclamar. Para temas fiscales y de facturación electrónica, la referencia oficial es la Agencia Tributaria. Si quieres dar un paso más con modelos de lenguaje, echa un ojo a leer facturas con IA.

Preguntas frecuentes

¿Necesito saber programar para leer facturas con Python?

No hace falta ser programador, pero sí manejarte con lo básico: variables, funciones, listas y saber ejecutar un script. Con un tutorial de fin de semana y copiar los ejemplos de esta guía puedes tener tu primer extractor funcionando. Si te atascas, Google Colab tiene una comunidad enorme con ejemplos listos para adaptar.

¿Qué librería de Python es mejor para leer facturas en PDF?

Depende del PDF. Si tiene texto seleccionable, pdfplumber es la opción más cómoda porque también extrae tablas. PyPDF2 es más ligero pero menos flexible. Si el PDF es un escaneo, ninguna de las dos sirve: necesitas convertir a imagen y aplicar OCR con pytesseract.

¿Funciona el OCR con cualquier factura escaneada?

No con cualquier calidad. El OCR necesita imágenes nítidas, rectas y con buen contraste. Una foto torcida o con sombras dará resultados pobres. Para facturas importantes, revisa siempre el texto extraído antes de fiarte. Y si puedes, pide al proveedor el PDF original o el XML.

¿Puedo usar Python para leer facturas de la luz, agua o teléfono?

Sí, siempre que sean PDF con texto o XML. Las comercializadoras suelen ofrecer la factura en PDF descargable desde su área de cliente, y muchas ya permiten descargar el XML Facturae. El proceso es el mismo: extraer texto, aplicar regex para importe, fecha y proveedor, y guardar en CSV.

Para tus propias facturas, sí. El problema aparece si subes facturas de terceros (con sus datos personales) a servicios en la nube sin su consentimiento, porque podrías incumplir el RGPD. Para uso personal, el OCR local con Tesseract evita enviar nada fuera de tu equipo.

¿Cómo evito que el script falle cuando cambia el formato de la factura?

Escribe regex flexibles (por ejemplo, Total(?:\s+a\s+pagar)? en lugar de exigir la frase exacta), valida que los importes estén en un rango razonable y guarda siempre el nombre del archivo original. Si una factura falla, el script debe registrar el error y seguir con la siguiente, no detenerse. Revisa los fallos cada pocos meses y ajusta los patrones.

R
Redacción de Cuentas al Punto

Analizamos tarifas, bancos y trámites para explicarte en lenguaje llano cómo gastar menos y decidir mejor con tu dinero. Revisamos y actualizamos cada guía cuando cambian las condiciones.

Cómo trabajamos →