pdfplumber vs PyMuPDF — velocidad, tablas y licencias
pdfplumber y PyMuPDF son bibliotecas de PDF populares en Python, pero ambas te obligan a hacer concesiones. pdfplumber es excelente para tablas, pero 29× más lento de lo necesario. PyMuPDF es rápido, pero está atado a la licencia AGPL-3.0, que bloquea el uso comercial. Esta página compara ambas — y muestra por qué PDF Oxide es la mejor opción para la mayoría de los casos de uso.
La respuesta corta: PDF Oxide es 29× más rápido que pdfplumber, 5,8× más rápido que PyMuPDF, tiene licencia MIT y maneja texto, imágenes, formularios, cifrado, salida en Markdown y OCR — todo en una sola biblioteca. La única área en la que pdfplumber sigue liderando es la extracción de tablas complejas con depuración visual.
Comparación rápida
| pdfplumber | PyMuPDF | PDF Oxide | |
|---|---|---|---|
| Licencia | MIT | AGPL-3.0 | MIT |
| Lenguaje | Python puro | C (MuPDF) | Rust + PyO3 |
| Tiempo medio de extracción | 23,2ms | 4,6ms | 0,8ms |
| Tiempo de extracción p99 | 189ms | 28ms | 9ms |
| Tasa de éxito (3830 PDF) | 98,8% | 99,3% | 100% |
| Extracción de texto | Sí | Sí | Sí |
| Posiciones de caracteres | Sí | Sí | Sí |
| Extracción de tablas | Avanzada | Básica | Básica |
| Extracción de imágenes | No | Sí | Sí |
| Depuración visual | Sí | No | No |
| Creación de PDF | No | Sí | Sí |
| Edición de PDF | No | Sí | Sí |
| Salida en Markdown | No | No | Sí |
| Salida en HTML | No | No | Sí |
| Campos de formulario | Solo lectura | Lectura + escritura | Lectura + escritura |
| Cifrado | No | Lectura + escritura | Lectura + escritura |
| Renderizado | No | Sí | Sí |
| OCR | No | Tesseract | Integrado (PaddleOCR) |
| Tamaño de instalación | ~1 MB | ~20 MB | ~5 MB |
| Versiones de Python | 3.8+ | 3.8–3.12 | 3.8–3.14 |
Pruebas de velocidad
Las tres bibliotecas se evaluaron sobre el mismo corpus de 3830 PDF, reunido a partir de tres suites de pruebas públicas e independientes (veraPDF, Mozilla pdf.js, DARPA SafeDocs). El corpus abarca todas las versiones de la especificación PDF (1.0–2.0), archivos cifrados, documentos malformados, codificaciones CJK y diseños complejos.
| Métrica | pdfplumber | PyMuPDF | PDF Oxide |
|---|---|---|---|
| Tiempo medio de extracción | 23,2ms | 4,6ms | 0,8ms |
| Tiempo de extracción p99 | 189ms | 28ms | 9ms |
| En relación con PDF Oxide | 29x más lento | 5,8x más lento | 1x |
| Tasa de éxito (PDF válidos) | 98,8% (3777/3823) | 99,3% (3796/3823) | 100% (3823/3823) |
PyMuPDF es aproximadamente 5x más rápido que pdfplumber porque delega todo el análisis sintáctico a la biblioteca C MuPDF. pdfplumber se apoya en pdfminer para el análisis y luego añade su propia capa de análisis espacial — ambos escritos en Python puro. PDF Oxide realiza todo el análisis, la decodificación de fuentes y el ensamblaje de texto en Rust compilado, que se ejecuta directamente en el proceso de Python mediante PyO3, lo que explica su ventaja de 5,8x sobre PyMuPDF y de 29x sobre pdfplumber.
Qué significan las cifras en la práctica
| Carga de trabajo | pdfplumber | PyMuPDF | PDF Oxide |
|---|---|---|---|
| 100 PDF | 2,3 segundos | 0,46 segundos | 0,08 segundos |
| 1000 PDF | 23 segundos | 4,6 segundos | 0,8 segundos |
| 10 000 PDF | 3,9 minutos | 46 segundos | 8 segundos |
| 100 000 PDF | 39 minutos | 7,7 minutos | 80 segundos |
Para scripts puntuales que procesan un puñado de archivos, la diferencia de velocidad es irrelevante. Para canalizaciones de producción que procesan miles de documentos al día, la brecha entre 39 minutos y 80 segundos cambia las decisiones de arquitectura.
Extracción de tablas
La extracción de tablas es la razón principal por la que los desarrolladores eligen pdfplumber en lugar de PyMuPDF. Aquí es donde pdfplumber realmente brilla.
pdfplumber: análisis estructurado de tablas
pdfplumber ofrece una extracción de tablas dedicada, con detección de líneas configurable, fusión de celdas y depuración visual:
import pdfplumber
with pdfplumber.open("invoice.pdf") as pdf:
page = pdf.pages[0]
# Extract all tables as structured data
tables = page.extract_tables()
for table in tables:
for row in table:
print(row)
# Fine-tune detection with custom settings
tables = page.extract_tables({
"vertical_strategy": "text",
"horizontal_strategy": "lines",
"snap_tolerance": 5,
})
# Visual debugging: render page with detected table boundaries
im = page.to_image()
im.debug_tablefinder()
im.save("debug.png")
pdfplumber devuelve datos estructurados de filas/columnas y maneja celdas fusionadas, encabezados que abarcan varias columnas y tablas sin bordes. La superposición de depuración visual resulta inestimable para ajustar los parámetros de extracción en diseños complicados.
PyMuPDF: detección básica de tablas
PyMuPDF añadió la detección de tablas en versiones recientes, pero es menos madura que los algoritmos de pdfplumber:
import fitz
doc = fitz.open("invoice.pdf")
page = doc[0]
# PyMuPDF's built-in table finder (added in v1.23)
tabs = page.find_tables()
for table in tabs:
df = table.to_pandas() # requires pandas
print(df)
La extracción de tablas de PyMuPDF funciona con tablas sencillas de cuadrícula con bordes visibles. Le cuesta con los diseños sin bordes, los encabezados de varios niveles y las celdas que abarcan varias filas o columnas — exactamente los casos en los que pdfplumber es más fuerte.
PDF Oxide: salida de tablas en Markdown
PDF Oxide convierte las tablas a sintaxis Markdown como parte de su canalización de salida estructurada:
from pdf_oxide import PdfDocument
doc = PdfDocument("invoice.pdf")
# Tables are detected and converted to Markdown table format
md = doc.to_markdown(0, detect_headings=True)
print(md)
# Also available as HTML with table tags
html = doc.to_html(0)
print(html)
La detección de tablas de PDF Oxide es funcional para diseños de cuadrícula estándar y produce una salida limpia en Markdown o HTML. Para tablas complejas con celdas fusionadas, diseños sin bordes o encabezados que abarcan varias columnas, los algoritmos dedicados de pdfplumber siguen siendo más robustos.
Resumen de la extracción de tablas
| Capacidad | pdfplumber | PyMuPDF | PDF Oxide |
|---|---|---|---|
| Tablas sencillas con bordes | Sí | Sí | Sí |
| Tablas sin bordes | Sí | Limitado | Limitado |
| Celdas fusionadas | Sí | Limitado | Limitado |
| Encabezados de varios niveles | Sí | No | No |
| Detección configurable | Sí | Limitado | No |
| Depuración visual | Sí | No | No |
| Formato de salida | Listas de Python | DataFrames de pandas | Markdown / HTML |
| Velocidad | Lento (Python puro) | Rápido | El más rápido |
Si la extracción de tablas complejas es tu único caso de uso, pdfplumber es la mejor herramienta. Si necesitas tablas junto con extracción rápida de texto, extracción de imágenes o creación de PDF, PDF Oxide cubre más terreno.
Extracción de texto
Para la extracción de texto plano, ambas bibliotecas cumplen su cometido, pero difieren en velocidad y diseño de API.
pdfplumber
import pdfplumber
with pdfplumber.open("report.pdf") as pdf:
page = pdf.pages[0]
text = page.extract_text()
print(text)
PyMuPDF
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
text = page.get_text()
print(text)
PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
print(text)
Las tres producen una salida de texto comparable para PDF bien formados. PDF Oxide logra una paridad de texto del 99,5% con PyMuPDF en todo el corpus, y el 0,5% de diferencia restante se debe a la normalización de espacios en blanco y al manejo de ligaduras.
Posicionamiento a nivel de carácter
Tanto pdfplumber como PyMuPDF proporcionan datos de posición a nivel de carácter, lo cual es importante para el análisis espacial, la detección de cuadros delimitadores y la reconstrucción personalizada de diseños.
pdfplumber
import pdfplumber
with pdfplumber.open("report.pdf") as pdf:
page = pdf.pages[0]
for char in page.chars[:10]:
print(f"'{char['text']}' at ({char['x0']:.1f}, {char['top']:.1f}) "
f"size={char['size']:.1f}")
PyMuPDF
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
blocks = page.get_text("dict")["blocks"]
for block in blocks:
if "lines" in block:
for line in block["lines"]:
for span in line["spans"]:
print(f"'{span['text']}' size={span['size']:.1f}")
PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
chars = doc.extract_chars(0)
for ch in chars[:10]:
print(f"'{ch.char}' at ({ch.x:.1f}, {ch.y:.1f}) size={ch.font_size:.1f}")
pdfplumber devuelve diccionarios por carácter con metadatos detallados. PyMuPDF devuelve estructuras anidadas de bloque/línea/span. PDF Oxide devuelve objetos de carácter planos con datos de posición y fuente.
Licencias
Para los proyectos comerciales, esta es la diferencia más trascendental entre pdfplumber y PyMuPDF.
| pdfplumber | PyMuPDF | PDF Oxide | |
|---|---|---|---|
| Licencia | MIT | AGPL-3.0 | MIT |
| Producto comercial | Sí | Requiere licencia comercial | Sí |
| SaaS de código cerrado | Sí | Requiere licencia comercial | Sí |
| Distribución con Docker | Sí | Requiere licencia comercial | Sí |
| Herramientas internas | Sí | Sí | Sí |
| Proyecto de código abierto | Sí | Sí (si es compatible con AGPL) | Sí |
El problema de la AGPL en PyMuPDF
PyMuPDF envuelve a MuPDF, que tiene licencia AGPL-3.0. Si distribuyes software que incluya PyMuPDF — incluidos SaaS, aplicaciones web y contenedores Docker — tu código debe publicarse como código abierto bajo AGPL o debes comprar una licencia comercial a Artifex.
Artifex no publica abiertamente los precios de la licencia comercial. Debes contactar a su equipo de ventas para obtener un presupuesto. Las licencias suelen ser por aplicación, se renuevan anualmente, sin nivel gratuito ni excepción para startups.
pdfplumber y PDF Oxide son ambos MIT
Tanto pdfplumber como PDF Oxide tienen licencia MIT. Usa cualquiera de los dos en cualquier proyecto — comercial, propietario, SaaS o de código abierto — sin obligaciones. Si la licencia es tu principal preocupación y estás eligiendo entre pdfplumber y PyMuPDF, pdfplumber (o PDF Oxide) es la opción más segura.
PDF cifrados
El manejo del cifrado es una carencia importante en el conjunto de funciones de pdfplumber y un punto de dolor habitual para los desarrolladores que trabajan con documentos protegidos por contraseña.
pdfplumber: sin compatibilidad con cifrado
pdfplumber no puede abrir en absoluto PDF cifrados o protegidos por contraseña. Si le pasas un PDF cifrado a pdfplumber, lanza un error. Primero debes descifrar el archivo con otra herramienta:
import pdfplumber
# This will fail on encrypted PDFs:
with pdfplumber.open("encrypted.pdf") as pdf:
# raises pdfminer.pdfparser.PDFSyntaxError or similar
pass
Una solución común es usar PyMuPDF o pypdf para descifrar primero el archivo y luego pasárselo a pdfplumber para la extracción de tablas — añadiendo otra dependencia a tu canalización.
PyMuPDF: compatibilidad total con cifrado
import fitz
doc = fitz.open("encrypted.pdf")
doc.authenticate("password")
page = doc[0]
text = page.get_text()
PyMuPDF admite tanto contraseñas de usuario como de propietario, cifrado AES-128 y AES-256, y puede crear PDF cifrados.
PDF Oxide: compatibilidad total con cifrado
from pdf_oxide import PdfDocument
doc = PdfDocument("encrypted.pdf", password="password")
text = doc.extract_text(0)
PDF Oxide maneja todos los métodos estándar de cifrado de PDF (RC4, AES-128, AES-256) tanto para lectura como para escritura. No requiere dependencias adicionales ni preprocesamiento.
Extracción de imágenes
Otra carencia en el conjunto de funciones de pdfplumber. pdfplumber no extrae imágenes incrustadas de los PDF.
PyMuPDF
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
for i, img in enumerate(page.get_images()):
xref = img[0]
base_image = doc.extract_image(xref)
with open(f"image_{i}.{base_image['ext']}", "wb") as f:
f.write(base_image["image"])
PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
images = doc.extract_image_bytes(0)
for i, img in enumerate(images):
with open(f"image_{i}.{img['format']}", "wb") as f:
f.write(img["data"])
Si tu canalización necesita extraer tanto texto como imágenes de los PDF, pdfplumber no puede encargarse de la parte de las imágenes. Para eso necesitas PyMuPDF, PDF Oxide o pypdfium2.
Salida en Markdown y HTML
Ni pdfplumber ni PyMuPDF ofrecen una conversión integrada a Markdown o HTML. Esta es una función exclusiva de PDF Oxide.
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
# Markdown with heading detection and table formatting
md = doc.to_markdown(0, detect_headings=True)
print(md)
# HTML with semantic tags
html = doc.to_html(0)
print(html)
Para canalizaciones de LLM, sistemas RAG y flujos de conversión de documentos, la salida estructurada en Markdown elimina la necesidad de un paso de conversión aparte. Los usuarios de PyMuPDF suelen recurrir al paquete independiente pymupdf4llm, que es 69x más lento que la conversión integrada de PDF Oxide.
Cuándo elegir cada biblioteca
Elige pdfplumber si:
- La extracción de tablas complejas es tu caso de uso principal. Los algoritmos de tablas de pdfplumber manejan las celdas fusionadas, las tablas sin bordes y los encabezados que abarcan varias columnas mejor que cualquier otra biblioteca de Python.
- Necesitas depuración visual. pdfplumber puede renderizar imágenes de página anotadas que muestran las líneas, los caracteres y los límites de tabla detectados — inestimable para ajustar la extracción en documentos complicados.
- Quieres una solución en Python puro. Sin dependencias compiladas, se instala en cualquier lugar donde se ejecute Python.
- La velocidad no es una preocupación. Si procesas menos de un centenar de archivos a la vez, una media de 23ms es perfectamente aceptable.
Elige PyMuPDF si:
- Ya tienes una licencia comercial de MuPDF y dependes del renderizado específico de MuPDF o de la exportación a SVG.
- Necesitas un renderizado de alta fidelidad. El motor de renderizado de MuPDF es maduro y maneja bien los PDF complejos.
- Tu proyecto es compatible con AGPL. Si estás construyendo software de código abierto bajo AGPL o una licencia compatible, la licencia de PyMuPDF no es un problema.
- Necesitas OCR a través de Tesseract. PyMuPDF tiene integración con Tesseract incorporada para documentos escaneados.
Elige PDF Oxide si:
- Necesitas velocidad y una amplia cobertura de funciones. Una media de 0,8ms de extracción — 5,8x más rápido que PyMuPDF, 29x más rápido que pdfplumber — con texto, imágenes, formularios, creación y cifrado en una sola biblioteca.
- Quieres licencia MIT sin sacrificar velocidad. pdfplumber es MIT pero lento. PyMuPDF es rápido pero AGPL. PDF Oxide es a la vez MIT y rápido.
- Necesitas salida en Markdown o HTML. Conversión estructurada integrada para canalizaciones de LLM y sistemas RAG.
- Necesitas compatibilidad con PDF cifrados bajo una licencia permisiva. pdfplumber no puede manejar el cifrado. PyMuPDF puede, pero exige cumplir con la AGPL. PDF Oxide maneja el cifrado bajo MIT.
- Quieres una sola biblioteca para extracción, creación y edición. Tanto pdfplumber como PyMuPDF requieren herramientas adicionales para partes del flujo de trabajo de PDF. PDF Oxide cubre extracción, creación, edición, renderizado y validación.
Usa PDF Oxide + pdfplumber juntos:
Para canalizaciones que necesitan extracción rápida de texto, extracción de imágenes y análisis de tablas complejas, usa PDF Oxide para la canalización general y pdfplumber para las tablas:
from pdf_oxide import PdfDocument
import pdfplumber
# Fast text and image extraction with PDF Oxide
doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
images = doc.extract_images(0)
# Complex table extraction with pdfplumber
with pdfplumber.open("report.pdf") as pdf:
tables = pdf.pages[0].extract_tables()
Instalación
# pdfplumber
pip install pdfplumber
# PyMuPDF
pip install pymupdf
# PDF Oxide
pip install pdf_oxide
Las tres se instalan mediante pip. pdfplumber y PDF Oxide tienen licencia MIT. PyMuPDF es AGPL-3.0 — revisa las implicaciones de la licencia antes de añadirlo a un proyecto comercial.
El veredicto
pdfplumber y PyMuPDF resuelven cada uno partes del problema. PDF Oxide lo resuelve por completo.
| Lo que te importa | Mejor opción |
|---|---|
| Máxima velocidad | PDF Oxide (0,8ms — 29× más rápido que pdfplumber) |
| Extracción de tablas complejas | pdfplumber (depuración visual, celdas fusionadas) |
| Licencia permisiva + velocidad | PDF Oxide — pdfplumber es MIT pero lento, PyMuPDF es rápido pero AGPL |
| PDF cifrados | PDF Oxide o PyMuPDF — pdfplumber no puede descifrar |
| Extracción de imágenes | PDF Oxide o PyMuPDF — pdfplumber no admite imágenes |
| Salida en Markdown/HTML | PDF Oxide — la única biblioteca con conversión integrada |
| OCR sin Tesseract | PDF Oxide — PaddleOCR integrado |
| Una biblioteca para todo | PDF Oxide — extracción, creación, edición, cifrado, OCR |
A menos que todo tu flujo de trabajo sea la extracción de tablas complejas (tablas sin bordes, celdas fusionadas, depuración visual), PDF Oxide reemplaza tanto a pdfplumber como a PyMuPDF — más rápido, con más funciones, con licencia MIT.
Empieza en 10 segundos:
pip install pdf_oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
text = doc.extract_text(0) # 29× faster than pdfplumber
md = doc.to_markdown(0) # built-in, no separate package
images = doc.extract_images(0) # pdfplumber can't do this
Páginas relacionadas
- PDF Oxide vs PyMuPDF — comparación detallada con guía de migración
- PDF Oxide vs pdfplumber — comparación detallada con ejemplos de código
- vs Bibliotecas PDF de Python — todas las bibliotecas de Python comparadas
- Pruebas de rendimiento — metodología completa de pruebas sobre el corpus
- Extraer tablas de PDF — guía de extracción de tablas
- Primeros pasos con Python — instalación y primera extracción