vs Bibliotecas PDF para Python
PDF Oxide comparado con PyMuPDF (fitz), pypdfium2, pypdf, pdfplumber, pdfminer y otras. Esta página cubre el rendimiento, la cobertura de funciones, las licencias y las diferencias de API para ayudarte a elegir la biblioteca PDF para Python adecuada para la extracción de texto.
Resumen
| PDF Oxide | PyMuPDF | pypdfium2 | pypdf | pdfplumber | pdfminer | |
|---|---|---|---|---|---|---|
| Tiempo medio de extracción | 0.8ms | 4.6ms | 4.1ms | 12.1ms | 23.2ms | 16.8ms |
| Tasa de aprobación (3830 PDF) | 100% | 99.3% | 99.2% | 98.4% | 98.8% | 98.8% |
| Licencia | MIT | AGPL-3.0 | Apache-2.0 | BSD-3 | MIT | MIT |
| Lenguaje | Rust + PyO3 | C (MuPDF) | C (PDFium) | Pure Python | Pure Python | Pure Python |
| Extracción de texto | Sí | Sí | Sí | Sí | Sí | Sí |
| Posiciones de caracteres | Sí | Sí | Sí | Parcial | Sí | Sí |
| Extracción de imágenes | Sí | Sí | Sí | Sí | No | No |
| Campos de formulario | Lectura + escritura | Lectura + escritura | Solo lectura | Lectura + escritura | Solo lectura | No |
| Creación de PDF | Sí | Sí | No | Limitada | No | No |
| Edición de PDF | Sí | Sí | No | Sí | No | No |
| Salida en Markdown | Sí | No | No | No | No | No |
| Salida en HTML | Sí | No | No | No | No | No |
| Cifrado | Lectura + escritura | Lectura + escritura | Solo lectura | Lectura + escritura | No | No |
| Validación PDF/A | Sí | No | No | No | No | No |
| Renderizado | Sí | Sí | Sí | No | No | No |
| Búsqueda | Regex + espacial | Sí | Sí | No | No | No |
| Versiones de Python | 3.8–3.14 | 3.8–3.12 | 3.8+ | 3.6+ | 3.8+ | 3.6+ |
| Tamaño de instalación | wheel de ~5 MB | wheel de ~20 MB | wheel de ~3 MB | ~1 MB | ~1 MB | ~1 MB |
Comparación de rendimiento
Tiempo medio de extracción de texto por PDF, medido sobre el corpus completo de 3830 PDF: tres conjuntos de pruebas independientes y disponibles públicamente que, en conjunto, cubren todas las versiones de la especificación PDF (1.0–2.0), archivos cifrados, documentos mal formados, codificaciones CJK, diseños complejos y casos límite de seguridad. Consulta los detalles completos del corpus para saber qué prueba cada conjunto y por qué estos resultados son reproducibles.
| Biblioteca | Media | Relativo | p99 | Tasa de aprobación |
|---|---|---|---|---|
| PDF Oxide | 0.8ms | 1× | 9ms | 100% |
| PyMuPDF | 4.6ms | 5.8× | 28ms | 99.3% |
| pypdfium2 | 4.1ms | 5.1× | 42ms | 99.2% |
| pymupdf4llm | 55.5ms | 69× | 280ms | 99.1% |
| pdftext | 7.3ms | 9.1× | 82ms | 99.0% |
| pdfminer | 16.8ms | 21× | 124ms | 98.8% |
| pdfplumber | 23.2ms | 29× | 189ms | 98.8% |
| markitdown | 108.8ms | 136× | 378ms | 98.6% |
| pypdf | 12.1ms | 15.1× | 97ms | 98.4% |
PDF Oxide alcanza su velocidad gracias a un núcleo nativo en Rust compilado como módulo de extensión de Python mediante PyO3. No hay sobrecarga de subprocesos ni puentes a bibliotecas C: el código Rust se ejecuta directamente en el proceso de Python.
Fiabilidad
PDF Oxide procesa 3823 de 3823 PDF válidos sin fallos: una tasa de aprobación del 100 %. Los 7 archivos que no aprobaron en el corpus de 3830 archivos son fixtures de prueba dañados a propósito (encabezado PDF ausente, catálogos corrompidos por fuzzing, flujos xref no válidos).
| Biblioteca | PDF válidos aprobados | Tasa de aprobación |
|---|---|---|
| PDF Oxide | 3,823 / 3,823 | 100% |
| PyMuPDF | 3,796 / 3,823 | 99.3% |
| pypdfium2 | 3,792 / 3,823 | 99.2% |
| pymupdf4llm | 3,787 / 3,823 | 99.1% |
| pdftext | 3,784 / 3,823 | 99.0% |
| pdfminer | 3,777 / 3,823 | 98.8% |
| pdfplumber | 3,777 / 3,823 | 98.8% |
| markitdown | 3,771 / 3,823 | 98.6% |
| pypdf | 3,762 / 3,823 | 98.4% |
Calidad del texto
PDF Oxide alcanza una paridad de texto del 99,5 % en comparación con PyMuPDF y pypdfium2 en todo el corpus. La calidad se midió comparando la salida de texto extraído carácter por carácter. El 0,5 % de diferencia restante se debe a la normalización de espacios en blanco y al manejo de ligaduras, donde PDF Oxide produce una salida más limpia.
Comparación de licencias
| Biblioteca | Licencia | Uso comercial | Copyleft |
|---|---|---|---|
| PDF Oxide | MIT | Sin restricciones | No |
| pypdfium2 | Apache-2.0 | Sin restricciones | No |
| PyMuPDF | AGPL-3.0 | Requiere licencia comercial ($) | Sí |
| pypdf | BSD-3 | Sin restricciones | No |
| pdfplumber | MIT | Sin restricciones | No |
| pdfminer | MIT | Sin restricciones | No |
| pdftext | GPL-3.0 | Requiere código abierto | Sí |
PyMuPDF usa MuPDF bajo la licencia AGPL-3.0. Si distribuyes software que usa PyMuPDF, tu software también debe publicarse bajo AGPL-3.0, o bien debes comprar una licencia comercial a Artifex. Esto se aplica a productos SaaS, aplicaciones web y cualquier binario distribuido.
PDF Oxide tiene licencia MIT, sin restricciones. Úsalo en productos propietarios, plataformas SaaS o aplicaciones de código cerrado sin ninguna obligación de licencia.
| Caso de uso | PDF Oxide (MIT) | PyMuPDF (AGPL) | pypdfium2 (Apache) | pypdf (BSD) | pdfplumber (MIT) | pdfminer (MIT) |
|---|---|---|---|---|---|---|
| Producto comercial | Sí | Requiere licencia | Sí | Sí | Sí | Sí |
| Código cerrado | Sí | No (salvo con licencia) | Sí | Sí | Sí | Sí |
| SaaS/nube | Sí | Requiere licencia | Sí | Sí | Sí | Sí |
| Herramientas internas | Sí | Sí | Sí | Sí | Sí | Sí |
Comparación de API
Extracción de texto
PDF Oxide:
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
print(text)
PyMuPDF:
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
text = page.get_text()
print(text)
pypdf:
from pypdf import PdfReader
reader = PdfReader("report.pdf")
page = reader.pages[0]
text = page.extract_text()
print(text)
pdfplumber:
import pdfplumber
with pdfplumber.open("report.pdf") as pdf:
page = pdf.pages[0]
text = page.extract_text()
print(text)
pdfminer:
from pdfminer.high_level import extract_text
text = extract_text("report.pdf", page_numbers=[0])
print(text)
Extracción a nivel de carácter
PDF Oxide:
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
chars = doc.extract_chars(0)
for ch in chars:
print(f"'{ch.char}' at ({ch.bbox[0]:.1f}, {ch.bbox[1]:.1f}) "
f"size={ch.font_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}")
pdfplumber:
import pdfplumber
with pdfplumber.open("report.pdf") as pdf:
page = pdf.pages[0]
for char in page.chars:
print(f"'{char['text']}' at ({char['x0']:.1f}, {char['top']:.1f}) "
f"size={char['size']:.1f}")
pdfminer:
from pdfminer.high_level import extract_pages
from pdfminer.layout import LTChar
for page_layout in extract_pages("report.pdf"):
for element in page_layout:
if hasattr(element, '__iter__'):
for text_line in element:
if hasattr(text_line, '__iter__'):
for char in text_line:
if isinstance(char, LTChar):
print(f"'{char.get_text()}' at ({char.x0:.1f}, {char.y0:.1f}) "
f"size={char.size:.1f}")
Extracción de imágenes
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"])
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"])
pypdf:
from pypdf import PdfReader
reader = PdfReader("report.pdf")
page = reader.pages[0]
for i, image in enumerate(page.images):
with open(f"image_{i}.{image.name.split('.')[-1]}", "wb") as f:
f.write(image.data)
Creación de PDF
PDF Oxide:
from pdf_oxide import Pdf
pdf = Pdf.from_markdown("# Hello World\n\nThis is a PDF.")
pdf.save("output.pdf")
# Also supports HTML
pdf = Pdf.from_html("<h1>Hello</h1><p>World</p>")
pdf.save("output.pdf")
PyMuPDF:
import fitz
doc = fitz.open()
page = doc.new_page()
text_point = fitz.Point(72, 72)
page.insert_text(text_point, "Hello World", fontsize=24)
doc.save("output.pdf")
pypdf:
# pypdf can merge/modify PDFs but cannot create from scratch with text content.
# Use reportlab or fpdf2 for creation, then merge with pypdf.
PDF cifrados
PDF Oxide:
from pdf_oxide import PdfDocument
doc = PdfDocument("encrypted.pdf", password="password")
text = doc.extract_text(0)
PyMuPDF:
import fitz
doc = fitz.open("encrypted.pdf")
doc.authenticate("password")
page = doc[0]
text = page.get_text()
pypdf:
from pypdf import PdfReader
reader = PdfReader("encrypted.pdf")
reader.decrypt("password")
text = reader.pages[0].extract_text()
Salida en Markdown y HTML
PDF Oxide (función exclusiva):
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
# Convert to Markdown with heading detection
md = doc.to_markdown(0, detect_headings=True)
print(md)
# Convert to HTML
html = doc.to_html(0)
print(html)
Ninguna otra biblioteca PDF para Python ofrece conversión integrada a Markdown o HTML.
Perfiles de las bibliotecas
PDF Oxide
Fortalezas:
- La extracción de texto más rápida en las pruebas gracias al núcleo en Rust: 5,8× más rápida que PyMuPDF
- Tasa de aprobación del 100 % en el corpus de 3830 PDF: la mayor fiabilidad de todas las bibliotecas probadas
- API unificada para extracción, creación y edición en una sola biblioteca
- Exportación integrada a Markdown y HTML con detección de encabezados
- Licencia MIT sin restricciones de copyleft
- Validación de conformidad nativa (PDF/A, PDF/UA, PDF/X)
- Wheels precompilados para todas las plataformas principales y Python 3.8–3.14
- Sin dependencias del sistema: el wheel incluye todo
Limitaciones:
- Biblioteca más reciente con una comunidad más pequeña
- La extracción de tablas es básica en comparación con los algoritmos de pdfplumber
- El motor de renderizado es menos maduro que MuPDF
PyMuPDF (fitz)
Fortalezas:
- Madura y probada en producción (respaldada por MuPDF, en desarrollo desde 2005)
- Excelente calidad de renderizado para PDF complejos
- Integración de OCR incorporada (Tesseract)
- Amplio conjunto de funciones: exportación a SVG, manipulación de páginas, detección de tablas
Limitaciones:
- La licencia AGPL-3.0 obliga a abrir el código de tu aplicación o a comprar una licencia comercial
- Tamaño de wheel grande (~20 MB) por el MuPDF incluido
- Sin exportación integrada a Markdown
- Sin validación de conformidad
pypdfium2
Fortalezas:
- Rápida (respaldada por el motor PDFium de Google)
- Licencia Apache-2.0: permisiva para uso comercial
- Buena calidad de renderizado
Limitaciones:
- API de extracción de texto limitada en comparación con PDF Oxide o PyMuPDF
- Sin creación ni edición de PDF
- Sin soporte de campos de formulario más allá de solo lectura
pypdf
Fortalezas:
- Pure Python: se instala en cualquier lugar, sin dependencias compiladas
- Ligera y bien mantenida
- Buena para manipular PDF (combinar, dividir, rotar, cifrar)
- Comunidad amplia y documentación extensa
Limitaciones:
- 15× más lenta que PDF Oxide en la extracción de texto
- La calidad de extracción de texto sufre con diseños complejos
- Sin renderizado, sin exportación a Markdown/HTML, sin extracción de tablas
pdfplumber
Fortalezas:
- La mejor extracción de tablas de todas las bibliotecas PDF para Python
- Excelentes datos de posicionamiento a nivel de carácter
- Herramientas de depuración visual (imágenes de página anotadas)
- Licencia MIT
Limitaciones:
- Pure Python: 29× más lenta que PDF Oxide
- Solo lectura: sin creación ni edición de PDF
- Sin cifrado ni renderizado
pdfminer
Fortalezas:
- Análisis detallado de caracteres y diseño
- Buen soporte para texto CJK
- Base de pdfplumber y otras herramientas
- Licencia MIT
Limitaciones:
- 21× más lenta que PDF Oxide (Pure Python, sin optimizar)
- Solo lectura, sin creación ni edición
- API verbosa para tareas comunes
- Mantenimiento menos activo
Cuándo usar cada una
| Caso de uso | Biblioteca recomendada |
|---|---|
| Extracción de texto rápida | PDF Oxide |
| Producto comercial / propietario | PDF Oxide, pypdfium2, pypdf, pdfplumber o pdfminer |
| Alternativa a PyMuPDF (con licencia MIT) | PDF Oxide |
| Creación de PDF desde Markdown/HTML | PDF Oxide |
| Validación de conformidad (PDF/A, PDF/X) | PDF Oxide |
| Extracción de tablas de facturas | pdfplumber |
| Depuración visual de la extracción | pdfplumber |
| Inversión existente en MuPDF | PyMuPDF (si es compatible con AGPL) |
| Dependencias mínimas | pypdf (Pure Python) |
| Análisis detallado del diseño | pdfminer |
| OCR para documentos escaneados | PyMuPDF |
Instalación
# PDF Oxide
pip install pdf_oxide
# PyMuPDF
pip install pymupdf
# pypdfium2
pip install pypdfium2
# pypdf
pip install pypdf
# pdfplumber
pip install pdfplumber
# pdfminer
pip install pdfminer.six
PDF Oxide distribuye wheels precompilados para Linux (x86_64, aarch64), macOS (x86_64, arm64) y Windows (x86_64). No se requiere compilador ni bibliotecas del sistema.
Páginas relacionadas
- Pruebas de rendimiento – resultados de las pruebas sobre el corpus completo
- Primeros pasos con Python – instalación y primera extracción
- Referencia de la API de Python – API completa de Python
- vs Bibliotecas PDF para Rust – comparación del ecosistema Rust