Mejor biblioteca PDF de Python en 2026
PDF Oxide comparado con PyMuPDF (fitz), pypdfium2, pypdf, pdfplumber, pdfminer y más. Esta página revisa rendimiento, cobertura de funciones, licencia y diferencias de API para que elijas la biblioteca PDF de Python adecuada para extraer 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 éxito (3 830 PDFs) | 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) | Python puro | Python puro | Python puro |
| 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 Markdown | Sí | No | No | No | No | No |
| Salida 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 | ~5 MB wheel | ~20 MB wheel | ~3 MB wheel | ~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 3 830 PDFs — tres suites de pruebas independientes y públicas que en conjunto cubren todas las versiones de la especificación PDF (1.0–2.0), archivos cifrados, documentos corruptos, codificaciones CJK, disposiciones complejas y casos límite de seguridad. Consulta los detalles del corpus para ver qué prueba cada suite y por qué los resultados son reproducibles.
| Biblioteca | Media | Relativa | p99 | Tasa de éxito |
|---|---|---|---|---|
| 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 logra esta 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 con bibliotecas C — el código Rust se ejecuta directamente dentro del proceso de Python.
Fiabilidad
PDF Oxide procesa 3 823 de 3 823 PDFs válidos sin fallar — una tasa de éxito del 100 %. Los 7 archivos que no pasan dentro del corpus de 3 830 son fixtures de prueba rotas a propósito (sin cabecera PDF, catálogos corrompidos por fuzzing, streams xref inválidos).
| Biblioteca | PDFs válidos superados | Tasa de éxito |
|---|---|---|
| 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 textual del 99,5 % frente a PyMuPDF y pypdfium2 en todo el corpus. La calidad se midió comparando la salida extraída carácter a carácter. El 0,5 % restante está en la normalización de espacios en blanco y el tratamiento 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 use PyMuPDF, tu software también debe publicarse bajo AGPL-3.0 — o tienes que adquirir una licencia comercial de Artifex. Esto aplica a productos SaaS, aplicaciones web y cualquier binario distribuido.
PDF Oxide es MIT y no impone restricciones. Úsalo en productos propietarios, plataformas SaaS o aplicaciones de código cerrado sin obligaciones 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 (sin 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")
# También admite 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 puede combinar o modificar PDFs, pero no crear uno con texto desde cero.
# Usa reportlab o fpdf2 para crearlo y luego combina con pypdf.
PDFs 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 a Markdown y HTML
PDF Oxide (función única):
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
# Convertir a Markdown detectando encabezados
md = doc.to_markdown(0, detect_headings=True)
print(md)
# Convertir a HTML
html = doc.to_html(0)
print(html)
Ninguna otra biblioteca PDF de Python ofrece conversión a Markdown o HTML integrada.
Perfiles de cada biblioteca
PDF Oxide
Fortalezas:
- Extracción de texto más rápida en los benchmarks gracias a su núcleo en Rust — 5,8× más rápida que PyMuPDF
- 100 % de éxito en el corpus de 3 830 PDFs — la fiabilidad más alta de las bibliotecas probadas
- API unificada para extraer, crear y editar en una sola biblioteca
- Exportación a Markdown y HTML integrada con detección de encabezados
- Licencia MIT sin restricciones copyleft
- Validación de cumplimiento nativa (PDF/A, PDF/UA, PDF/X)
- Wheels precompilados para las plataformas principales y Python 3.8–3.14
- Sin dependencias de sistema — el wheel lo incluye todo
Limitaciones:
- Biblioteca más reciente, con una comunidad menor
- La extracción de tablas es básica frente a 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 PDFs complejos
- Integración OCR incorporada (Tesseract)
- Amplio conjunto de funciones: exportación SVG, manipulación de páginas, detección de tablas
Limitaciones:
- La licencia AGPL-3.0 exige abrir el código de tu aplicación o comprar una licencia comercial
- Wheel de gran tamaño (~20 MB) por incluir MuPDF
- Sin exportación Markdown integrada
- Sin validación de cumplimiento
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 comparada con PDF Oxide o PyMuPDF
- No permite crear ni editar PDFs
- Sin soporte de campos de formulario más allá de solo lectura
pypdf
Fortalezas:
- Python puro — se instala en cualquier sitio, sin dependencias compiladas
- Ligera y bien mantenida
- Buena para manipular PDFs (combinar, dividir, rotar, cifrar)
- Gran comunidad y documentación amplia
Limitaciones:
- 15× más lenta que PDF Oxide en extracción de texto
- La calidad de extracción sufre en disposiciones complejas
- Sin renderizado, sin exportación Markdown/HTML, sin extracción de tablas
pdfplumber
Fortalezas:
- Mejor extracción de tablas entre todas las bibliotecas PDF de Python
- Excelentes datos de posición a nivel de carácter
- Herramientas de depuración visual (imágenes de página anotadas)
- Licencia MIT
Limitaciones:
- Python puro — 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 disposición
- Buen soporte de texto CJK
- Base de pdfplumber y otras herramientas
- Licencia MIT
Limitaciones:
- 21× más lenta que PDF Oxide (Python puro, sin optimizar)
- Solo lectura, sin creación ni edición
- API verbosa para tareas habituales
- Mantenimiento menos activo
Cuándo usar cada una
| Caso de uso | Biblioteca recomendada |
|---|---|
| Extracción rápida de texto | PDF Oxide |
| Producto comercial / propietario | PDF Oxide, pypdfium2, pypdf, pdfplumber o pdfminer |
| Alternativa a PyMuPDF con licencia MIT | PDF Oxide |
| Crear PDF desde Markdown/HTML | PDF Oxide |
| Validación de cumplimiento (PDF/A, PDF/X) | PDF Oxide |
| Extracción de tablas en facturas | pdfplumber |
| Depuración visual de la extracción | pdfplumber |
| Ya inviertes en MuPDF | PyMuPDF (si AGPL es compatible) |
| Mínimas dependencias | pypdf (Python puro) |
| Análisis detallado de la disposición | pdfminer |
| OCR de 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 entrega wheels precompilados para Linux (x86_64, aarch64), macOS (x86_64, arm64) y Windows (x86_64). No hace falta compilador ni bibliotecas del sistema.
Páginas relacionadas
- Benchmarks de rendimiento – resultados completos sobre el corpus
- Primeros pasos con Python – instalación y primera extracción
- Referencia de la API de Python – API de Python completa
- vs bibliotecas PDF de Rust – comparación del ecosistema Rust