
Contenido del artículo
- Qué necesitas para empezar a leer facturas con Python
- Leer facturas en PDF: texto seleccionable vs. escaneado
- Extraer datos concretos: importe, fecha y proveedor
- Facturas en XML (Facturae): la vía más sencilla
- Usar OCR para facturas en papel o imágenes
- Clasificar y guardar los gastos automáticamente
- Errores comunes y cómo evitarlos
- Ejemplo práctico: de factura PDF a hoja de cálculo
- Nuestra recomendación final para automatizar tus facturas
- 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 →
pdfplumberoPyPDF2; PDF escaneado → OCR conpytesseract.- XML Facturae →
xml.etree.ElementTree, la vía más limpia y fiable.- Guarda todo con
pandasen 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

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

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
0conO,1conl, 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:
pdfplumbera veces devuelveóen vez deó. Normaliza conunicodedataotexto.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.
¿Es legal usar OCR o IA para procesar mis facturas?
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.




