Skip to content

Лучшая 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 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). Компилятор и системные библиотеки не требуются.

Связанные страницы