PDFs con Python: extrae texto con pdfplumber

Actualizado el: 21/08/2026
Tempo de leitura: 4 minutos
Extração de texto de arquivos PDF usando Python

Extraer texto de archivos PDF con Python es una tarea común en automatización, análisis documental, búsqueda interna y preparación de datos. Sin embargo, un PDF no siempre contiene texto de la misma manera. Algunos documentos guardan caracteres seleccionables, otros contienen tablas complejas y muchos son simplemente imágenes escaneadas. Por eso la herramienta adecuada depende del tipo de archivo.

Antes de empezar, conviene conocer el manejo de rutas con pathlib, las excepciones en Python, el procesamiento de archivos CSV y la creación de funciones reutilizables. También debes respetar la privacidad, los derechos de acceso y las restricciones legales de los documentos.

Elegir una biblioteca

Para texto normal, pypdf es una opción moderna y sencilla. Para diseños complejos y tablas, pdfplumber ofrece más control sobre posiciones y palabras. La documentación oficial de pypdf explica sus capacidades y limitaciones. El repositorio oficial de pdfplumber incluye ejemplos para texto, tablas y coordenadas.

Instalar las dependencias

python -m venv .venv
# Windows
.venv\Scripts\activate
# Linux o macOS
source .venv/bin/activate

python -m pip install pypdf pdfplumber

Utiliza un entorno virtual para evitar conflictos y guarda las versiones del proyecto en requirements.txt.

Extraer texto con pypdf

from pathlib import Path
from pypdf import PdfReader

ruta = Path("documento.pdf")
lector = PdfReader(ruta)

for numero, pagina in enumerate(lector.pages, start=1):
    texto = pagina.extract_text() or ""
    print(f"--- Página {numero} ---")
    print(texto)

extract_text() puede devolver None cuando no encuentra contenido textual. Por eso se utiliza or "".

Guardar todo el texto en un archivo

partes = []

for pagina in lector.pages:
    partes.append(pagina.extract_text() or "")

texto_completo = "\n\n".join(partes)
Path("documento.txt").write_text(texto_completo, encoding="utf-8")

Separar páginas con líneas vacías mejora la lectura. Para auditorías, puedes incluir marcadores como [PÁGINA 3].

Crear una función reutilizable

def extraer_texto_pdf(ruta_pdf: Path) -> str:
    lector = PdfReader(ruta_pdf)
    paginas = []

    for indice, pagina in enumerate(lector.pages, start=1):
        texto = pagina.extract_text() or ""
        paginas.append(f"[PÁGINA {indice}]\n{texto}")

    return "\n\n".join(paginas)

Esta función facilita las pruebas y permite usar el resultado en una API, un buscador o un proceso de clasificación.

Procesar una carpeta completa

entrada = Path("pdfs")
salida = Path("textos")
salida.mkdir(exist_ok=True)

for pdf in entrada.glob("*.pdf"):
    try:
        texto = extraer_texto_pdf(pdf)
        destino = salida / f"{pdf.stem}.txt"
        destino.write_text(texto, encoding="utf-8")
    except Exception as error:
        print(f"Error en {pdf.name}: {error}")

En producción, reemplaza print() por logging y registra qué documentos fallaron.

Manejar PDF protegidos

lector = PdfReader("protegido.pdf")

if lector.is_encrypted:
    resultado = lector.decrypt("contraseña")
    if resultado == 0:
        raise ValueError("No se pudo desbloquear el PDF")

No intentes evadir protecciones ni proceses documentos sin autorización. La contraseña debe recibirse desde una fuente segura, no escribirse en el código.

Extraer texto con pdfplumber

import pdfplumber

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

pdfplumber resulta especialmente útil cuando necesitas palabras con coordenadas:

with pdfplumber.open("documento.pdf") as pdf:
    palabras = pdf.pages[0].extract_words()
    for palabra in palabras[:10]:
        print(palabra)

Cada elemento puede incluir texto y posiciones como x0, x1, top y bottom.

Extraer tablas

with pdfplumber.open("informe.pdf") as pdf:
    tabla = pdf.pages[0].extract_table()

for fila in tabla or []:
    print(fila)

Las tablas en PDF no son verdaderas hojas de cálculo. Muchas veces solo son palabras dibujadas en posiciones específicas. La extracción puede requerir ajustes en líneas verticales, horizontales y tolerancias.

Convertir una tabla a CSV

import csv

if tabla:
    with open("tabla.csv", "w", newline="", encoding="utf-8") as archivo:
        escritor = csv.writer(archivo)
        escritor.writerows(tabla)

Después revisa encabezados, columnas desplazadas y celdas combinadas. No asumas que el resultado es correcto solo porque se generó un archivo.

PDF escaneados y OCR

Si no puedes seleccionar el texto en un visor, probablemente el PDF contiene imágenes. En ese caso necesitas OCR. Una estrategia común es convertir páginas a imágenes y usar Tesseract u otro motor. El OCR introduce errores, especialmente con baja resolución, columnas, tablas, fuentes pequeñas y documentos inclinados.

Antes de añadir OCR, comprueba si extract_text() devuelve muy poco contenido:

texto = extraer_texto_pdf(Path("documento.pdf"))
if len(texto.strip()) < 50:
    print("El documento puede necesitar OCR")

Este umbral es solo una señal; una página legítima también puede tener poco texto.

Limpiar el texto extraído

import re

def limpiar_texto(texto: str) -> str:
    texto = texto.replace("\u00ad", "")
    texto = re.sub(r"-\n(?=\w)", "", texto)
    texto = re.sub(r"[ \t]+", " ", texto)
    texto = re.sub(r"\n{3,}", "\n\n", texto)
    return texto.strip()

Eliminar guiones de final de línea puede unir palabras correctamente, pero también puede alterar términos que realmente llevan guion. Conserva una copia del texto original.

Extraer únicamente algunas páginas

lector = PdfReader("libro.pdf")
inicio = 10
fin = 20

for pagina in lector.pages[inicio:fin]:
    print(pagina.extract_text() or "")

Los índices empiezan en cero. La página visible 11 suele corresponder al índice 10, aunque portadas y numeración impresa pueden causar diferencias.

Validar archivos antes de procesar

def validar_pdf(ruta: Path, max_mb=50):
    if ruta.suffix.lower() != ".pdf":
        raise ValueError("Extensión no permitida")
    if not ruta.is_file():
        raise FileNotFoundError(ruta)
    if ruta.stat().st_size > max_mb * 1024 * 1024:
        raise ValueError("Archivo demasiado grande")

Los límites protegen al servidor contra archivos inesperadamente grandes. También puedes restringir el número de páginas.

Registrar metadatos

lector = PdfReader("documento.pdf")
print(lector.metadata)
print("Páginas:", len(lector.pages))

Los metadatos pueden incluir título, autor o fecha, pero no siempre son correctos ni confiables.

Procesamiento paralelo

Para muchos documentos, procesa varios archivos en paralelo con límites. No abras cientos al mismo tiempo. Empieza con pocos trabajadores y mide memoria, disco y CPU. Para OCR, la carga suele ser mucho mayor que para extracción textual.

Errores frecuentes

Los fallos más comunes son asumir que todo PDF contiene texto seleccionable, ignorar documentos protegidos, perder la separación entre páginas, confiar ciegamente en tablas extraídas, sobrescribir resultados y procesar archivos enormes sin límites. También debes manejar documentos corruptos y fuentes con codificaciones especiales.

Conclusión

pypdf es adecuado para extraer texto y metadatos de documentos convencionales, mientras que pdfplumber ofrece más control para tablas y posiciones. Los PDF escaneados requieren OCR. Un proceso confiable valida tamaño, permisos y número de páginas, conserva el texto original, registra errores y revisa la calidad del resultado. Con estas precauciones puedes convertir colecciones de PDF en texto buscable, CSV o datos preparados para análisis.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Imagem ilustrativa de conteúdo Python para YouTube
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    YouTube con Python: descarga vídeos propios con yt-dlp

    Descarga copias de tus propios vídeos o contenido autorizado con Python y yt-dlp, validación, historial, límites, FFmpeg y prácticas responsables.

    Ler mais

    Tempo de leitura: 6 minutos
    12/07/2026
    Automação de postagens no Twitter usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Tweepy: automatiza publicaciones en X con Python

    Automatiza publicaciones en X con Tweepy, credenciales seguras, validación, deduplicación, programación, logs y prácticas responsables contra el spam.

    Ler mais

    Tempo de leitura: 5 minutos
    12/07/2026
    Geração e edição de planilhas Excel usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Excel con Python: crea y edita con openpyxl

    Crea y edita Excel con Pandas y openpyxl: hojas, fórmulas, estilos, filtros, validación, gráficos, rutas seguras y manejo de archivos

    Ler mais

    Tempo de leitura: 4 minutos
    12/07/2026
    Gerando aplicativo APK Android com Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    APK Android con Python, Kivy y Buildozer

    Genera un APK Android con Python, Kivy y Buildozer: configuración, permisos, recursos, compilación, pruebas, almacenamiento, firma y publicación.

    Ler mais

    Tempo de leitura: 6 minutos
    12/07/2026
    Web scraper de notícias em Python com envio para Telegram
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Scraper de noticias con Python y Telegram

    Crea un scraper de noticias con Requests y Beautiful Soup, elimina duplicados y envía titulares a Telegram de forma segura

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Compactação de arquivos ZIP usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    zipfile: descomprime archivos ZIP con seguridad

    Descomprime archivos ZIP con Python de forma segura: valida rutas, evita Zip Slip, limita tamaños, verifica integridad y procesa archivos

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026