Cómo extraer texto de archivos PDF con Python

Publicado el: 11/07/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

    Automação de tarefas com Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    20 scripts de Python para automatizar tareas cotidianas

    Descubre 20 scripts de Python para organizar archivos, crear backups, procesar CSV, enviar correos, comprobar sitios y automatizar tareas seguras.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Comparando listas e diferenças entre arrays em Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo comparar dos listas en Python y encontrar diferencias

    Compara listas en Python con igualdad, sorted, sets y Counter, conserva duplicados, detecta registros modificados y evita errores frecuentes.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Automação em Python para organizar arquivos do computador
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo organizar automáticamente los archivos de tu PC con Python

    Organiza automáticamente archivos del PC con Python, pathlib y shutil, evitando sobrescrituras, descargas incompletas y movimientos sin registro.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Script Python configurado para iniciar junto com o Windows
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo ejecutar un script de Python al iniciar Windows

    Configura un script Python para iniciar con Windows usando la carpeta Inicio, archivos BAT, Task Scheduler, entornos virtuales, logs y

    Ler mais

    Tempo de leitura: 6 minutos
    11/07/2026
    Sistema de backup automático de arquivos usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Cómo automatizar copias de seguridad con Python

    Aprende a automatizar copias de seguridad con Python usando pathlib, shutil, fechas, verificación, registros y una estrategia segura de restauración.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Execução de comandos do terminal usando Python
    Automatización y Scripts
    Foto de perfil de Leandro Hirt da Academify

    Subprocess en Python: ejecutar comandos del terminal

    Aprende subprocess en Python para ejecutar comandos, capturar salida, manejar errores, establecer timeouts y evitar riesgos con shell=True.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026