Лучшая PDF-библиотека для Python в 2026
PDF Oxide в сравнении с PyMuPDF (fitz), pypdfium2, pypdf, pdfplumber, pdfminer и другими. На этой странице разобраны производительность, охват функций, лицензирование и отличия API — чтобы подобрать подходящую PDF-библиотеку Python для извлечения текста.
Сводка
| PDF Oxide | PyMuPDF | pypdfium2 | pypdf | pdfplumber | pdfminer | |
|---|---|---|---|---|---|---|
| Среднее время извлечения | 0,8ms | 4,6ms | 4,1ms | 12,1ms | 23,2ms | 16,8ms |
| Доля успеха (3 830 PDF) | 100% | 99,3% | 99,2% | 98,4% | 98,8% | 98,8% |
| Лицензия | MIT | AGPL-3.0 | Apache-2.0 | BSD-3 | MIT | MIT |
| Язык реализации | Rust + PyO3 | C (MuPDF) | C (PDFium) | Чистый Python | Чистый Python | Чистый Python |
| Извлечение текста | Да | Да | Да | Да | Да | Да |
| Позиции символов | Да | Да | Да | Частично | Да | Да |
| Извлечение изображений | Да | Да | Да | Да | Нет | Нет |
| Поля форм | Чтение + запись | Чтение + запись | Только чтение | Чтение + запись | Только чтение | Нет |
| Создание PDF | Да | Да | Нет | Ограниченно | Нет | Нет |
| Редактирование PDF | Да | Да | Нет | Да | Нет | Нет |
| Вывод в Markdown | Да | Нет | Нет | Нет | Нет | Нет |
| Вывод в HTML | Да | Нет | Нет | Нет | Нет | Нет |
| Шифрование | Чтение + запись | Чтение + запись | Только чтение | Чтение + запись | Нет | Нет |
| Проверка PDF/A | Да | Нет | Нет | Нет | Нет | Нет |
| Рендеринг | Да | Да | Да | Нет | Нет | Нет |
| Поиск | Regex + пространственный | Да | Да | Нет | Нет | Нет |
| Версии Python | 3.8–3.14 | 3.8–3.12 | 3.8+ | 3.6+ | 3.8+ | 3.6+ |
| Размер установки | ~5 МБ wheel | ~20 МБ wheel | ~3 МБ wheel | ~1 МБ | ~1 МБ | ~1 МБ |
Сравнение производительности
Среднее время извлечения текста на один PDF, измеренное на полном корпусе из 3 830 PDF — трёх независимых, публично доступных тестовых наборах, которые вместе охватывают все версии спецификации PDF (1.0–2.0), зашифрованные файлы, повреждённые документы, CJK-кодировки, сложные макеты и пограничные случаи безопасности. Полное описание набора смотрите в деталях корпуса — там видно, что проверяет каждая сьюта и почему результаты воспроизводимы.
| Библиотека | Среднее | Относительно | p99 | Доля успеха |
|---|---|---|---|---|
| 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 достигается благодаря нативному ядру на Rust, собранному в расширение Python через PyO3. Здесь нет накладных расходов на подпроцессы или связывание с C-библиотекой — Rust-код выполняется прямо в процессе Python.
Надёжность
PDF Oxide обрабатывает 3 823 из 3 823 валидных PDF без сбоев — доля успеха 100 %. Остальные 7 файлов в корпусе из 3 830 — это умышленно сломанные тестовые фикстуры (отсутствующий PDF-заголовок, повреждённые фаззингом каталоги, недействительные xref-потоки).
| Библиотека | Пройдено валидных PDF | Доля успеха |
|---|---|---|
| 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% |
Качество текста
PDF Oxide показывает 99,5 % совпадения текста с PyMuPDF и pypdfium2 на всём корпусе. Качество измерено посимвольным сравнением извлечённого текста. Оставшиеся 0,5 % расхождения приходятся на нормализацию пробелов и обработку лигатур — там PDF Oxide выдаёт более аккуратный результат.
Сравнение лицензий
| Библиотека | Лицензия | Коммерческое использование | Копилефт |
|---|---|---|---|
| PDF Oxide | MIT | Без ограничений | Нет |
| pypdfium2 | Apache-2.0 | Без ограничений | Нет |
| PyMuPDF | AGPL-3.0 | Нужна коммерческая лицензия ($) | Да |
| pypdf | BSD-3 | Без ограничений | Нет |
| pdfplumber | MIT | Без ограничений | Нет |
| pdfminer | MIT | Без ограничений | Нет |
| pdftext | GPL-3.0 | Нужен открытый исходный код | Да |
PyMuPDF использует MuPDF под лицензией AGPL-3.0. Если вы распространяете программу, которая обращается к PyMuPDF, её исходники тоже придётся публиковать под AGPL-3.0 — либо покупать коммерческую лицензию у Artifex. Это касается SaaS-продуктов, веб-приложений и любых распространяемых бинарников.
PDF Oxide распространяется под MIT без каких-либо ограничений. Применяйте его в проприетарных продуктах, SaaS-платформах или приложениях с закрытым кодом — без обязательств по лицензии.
| Сценарий | PDF Oxide (MIT) | PyMuPDF (AGPL) | pypdfium2 (Apache) | pypdf (BSD) | pdfplumber (MIT) | pdfminer (MIT) |
|---|---|---|---|---|---|---|
| Коммерческий продукт | Да | Нужна лицензия | Да | Да | Да | Да |
| Закрытый код | Да | Нет (без лицензии) | Да | Да | Да | Да |
| SaaS/облако | Да | Нужна лицензия | Да | Да | Да | Да |
| Внутренние инструменты | Да | Да | Да | Да | Да | Да |
Сравнение API
Извлечение текста
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)
Извлечение по символам
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}")
Извлечение изображений
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)
Создание PDF
PDF Oxide:
from pdf_oxide import Pdf
pdf = Pdf.from_markdown("# Hello World\n\nThis is a PDF.")
pdf.save("output.pdf")
# Также поддерживается 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 умеет объединять и изменять PDF, но не создавать с нуля документ с текстом.
# Сгенерируйте PDF через reportlab или fpdf2, а затем объедините с помощью pypdf.
Зашифрованные PDF
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()
Вывод в Markdown и HTML
PDF Oxide (уникальная возможность):
from pdf_oxide import PdfDocument
doc = PdfDocument("paper.pdf")
# Конвертация в Markdown с распознаванием заголовков
md = doc.to_markdown(0, detect_headings=True)
print(md)
# Конвертация в HTML
html = doc.to_html(0)
print(html)
Ни одна другая PDF-библиотека для Python не содержит встроенной конвертации в Markdown или HTML.
Профили библиотек
PDF Oxide
Сильные стороны:
- Самое быстрое извлечение текста в бенчмарках благодаря ядру на Rust — в 5,8× быстрее PyMuPDF
- 100 % успеха на корпусе из 3 830 PDF — самая высокая надёжность среди протестированных библиотек
- Единый API для извлечения, создания и редактирования в одной библиотеке
- Встроенный экспорт в Markdown и HTML с распознаванием заголовков
- Лицензия MIT без копилефт-ограничений
- Нативная проверка соответствия (PDF/A, PDF/UA, PDF/X)
- Готовые wheel-сборки для основных платформ и Python 3.8–3.14
- Без системных зависимостей — всё необходимое уже в wheel
Ограничения:
- Более молодая библиотека с меньшим сообществом
- Извлечение таблиц проще, чем в алгоритмах pdfplumber
- Движок рендеринга менее зрелый, чем MuPDF
PyMuPDF (fitz)
Сильные стороны:
- Зрелая и проверенная в бою (на базе MuPDF, в разработке с 2005 года)
- Отличное качество рендеринга для сложных PDF
- Встроенная интеграция OCR (Tesseract)
- Богатый набор возможностей: экспорт SVG, манипуляции со страницами, распознавание таблиц
Ограничения:
- Лицензия AGPL-3.0 требует открывать исходники приложения или покупать коммерческую лицензию
- Крупный wheel (~20 МБ) из-за встроенного MuPDF
- Нет встроенного экспорта в Markdown
- Нет проверки соответствия
pypdfium2
Сильные стороны:
- Быстрая (на движке PDFium от Google)
- Лицензия Apache-2.0 — разрешительная для коммерческого применения
- Хорошее качество рендеринга
Ограничения:
- API извлечения текста ограничен по сравнению с PDF Oxide и PyMuPDF
- Нет создания и редактирования PDF
- Поля форм поддерживаются только на чтение
pypdf
Сильные стороны:
- Чистый Python — ставится где угодно, без нативных зависимостей
- Лёгкая и хорошо поддерживаемая
- Удобна для операций с PDF (объединение, разбиение, поворот, шифрование)
- Большое сообщество и обширная документация
Ограничения:
- В 15× медленнее PDF Oxide на извлечении текста
- Качество извлечения страдает на сложных макетах
- Нет рендеринга, экспорта в Markdown/HTML, распознавания таблиц
pdfplumber
Сильные стороны:
- Лучшее распознавание таблиц среди PDF-библиотек Python
- Отличные данные о позициях на уровне символов
- Визуальные средства отладки (страницы с разметкой)
- Лицензия MIT
Ограничения:
- Чистый Python — в 29× медленнее PDF Oxide
- Только чтение — нет создания и редактирования PDF
- Нет шифрования и рендеринга
pdfminer
Сильные стороны:
- Подробный анализ символов и раскладки
- Хорошая поддержка CJK-текста
- Основа для pdfplumber и других инструментов
- Лицензия MIT
Ограничения:
- В 21× медленнее PDF Oxide (чистый Python, без оптимизаций)
- Только чтение, без создания и редактирования
- Многословный API для типичных задач
- Менее активная поддержка
Когда что выбирать
| Сценарий | Рекомендуемая библиотека |
|---|---|
| Быстрое извлечение текста | PDF Oxide |
| Коммерческий / проприетарный продукт | PDF Oxide, pypdfium2, pypdf, pdfplumber или pdfminer |
| MIT-альтернатива PyMuPDF | PDF Oxide |
| Создание PDF из Markdown/HTML | PDF Oxide |
| Проверка соответствия (PDF/A, PDF/X) | PDF Oxide |
| Распознавание таблиц в счетах | pdfplumber |
| Визуальная отладка извлечения | pdfplumber |
| Уже вложились в MuPDF | PyMuPDF (если совместим с AGPL) |
| Минимум зависимостей | pypdf (чистый Python) |
| Подробный анализ раскладки | pdfminer |
| OCR отсканированных документов | PyMuPDF |
Установка
# 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 поставляет собранные wheel для Linux (x86_64, aarch64), macOS (x86_64, arm64) и Windows (x86_64). Компилятор и системные библиотеки не требуются.
Связанные страницы
- Бенчмарки производительности – полные результаты на корпусе
- Начало работы с Python – установка и первое извлечение
- Справочник Python API – полный Python API
- vs Rust-библиотеки PDF – сравнение в экосистеме Rust