pdfplumber vs PyMuPDF — скорость, таблицы и лицензирование
pdfplumber и PyMuPDF — популярные Python-библиотеки для работы с PDF, но обе вынуждают идти на компромиссы. pdfplumber отлично справляется с таблицами, но в 29 раз медленнее, чем необходимо. PyMuPDF быстра, но скована лицензией AGPL-3.0, которая блокирует коммерческое использование. Эта страница сравнивает обе библиотеки и показывает, почему PDF Oxide — лучший выбор для большинства сценариев.
Короткий ответ: PDF Oxide в 29 раз быстрее pdfplumber, в 5,8 раза быстрее PyMuPDF, имеет лицензию MIT и обрабатывает текст, изображения, формы, шифрование, вывод в Markdown и OCR — всё в одной библиотеке. Единственная область, где pdfplumber по-прежнему лидирует, — извлечение сложных таблиц с визуальной отладкой.
Краткое сравнение
| pdfplumber | PyMuPDF | PDF Oxide | |
|---|---|---|---|
| Лицензия | MIT | AGPL-3.0 | MIT |
| Язык | Чистый Python | C (MuPDF) | Rust + PyO3 |
| Среднее время извлечения | 23,2ms | 4,6ms | 0,8ms |
| Время извлечения p99 | 189ms | 28ms | 9ms |
| Доля успешных (3 830 PDF) | 98,8% | 99,3% | 100% |
| Извлечение текста | Да | Да | Да |
| Позиции символов | Да | Да | Да |
| Извлечение таблиц | Продвинутое | Базовое | Базовое |
| Извлечение изображений | Нет | Да | Да |
| Визуальная отладка | Да | Нет | Нет |
| Создание PDF | Нет | Да | Да |
| Редактирование PDF | Нет | Да | Да |
| Вывод в Markdown | Нет | Нет | Да |
| Вывод в HTML | Нет | Нет | Да |
| Поля форм | Только чтение | Чтение + запись | Чтение + запись |
| Шифрование | Нет | Чтение + запись | Чтение + запись |
| Рендеринг | Нет | Да | Да |
| OCR | Нет | Tesseract | Встроенный (PaddleOCR) |
| Размер установки | ~1 MB | ~20 MB | ~5 MB |
| Версии Python | 3.8+ | 3.8–3.12 | 3.8–3.14 |
Бенчмарки скорости
Все три библиотеки протестированы на одном и том же корпусе из 3 830 PDF, собранном из трёх независимых публичных тестовых наборов (veraPDF, Mozilla pdf.js, DARPA SafeDocs). Корпус охватывает все версии спецификации PDF (1.0–2.0), зашифрованные файлы, повреждённые документы, кодировки CJK и сложные макеты.
| Метрика | pdfplumber | PyMuPDF | PDF Oxide |
|---|---|---|---|
| Среднее время извлечения | 23,2ms | 4,6ms | 0,8ms |
| Время извлечения p99 | 189ms | 28ms | 9ms |
| Относительно PDF Oxide | в 29 раз медленнее | в 5,8 раза медленнее | 1x |
| Доля успешных (валидные PDF) | 98,8% (3 777/3 823) | 99,3% (3 796/3 823) | 100% (3 823/3 823) |
PyMuPDF примерно в 5 раз быстрее pdfplumber, потому что делегирует весь разбор C-библиотеке MuPDF. pdfplumber использует pdfminer для разбора, а затем добавляет собственный слой пространственного анализа — оба написаны на чистом Python. PDF Oxide выполняет весь разбор, декодирование шрифтов и сборку текста в скомпилированном Rust, работающем прямо в процессе Python через PyO3, что и обеспечивает её преимущество в 5,8 раза над PyMuPDF и в 29 раз над pdfplumber.
Что эти цифры значат на практике
| Нагрузка | pdfplumber | PyMuPDF | PDF Oxide |
|---|---|---|---|
| 100 PDF | 2,3 секунды | 0,46 секунды | 0,08 секунды |
| 1 000 PDF | 23 секунды | 4,6 секунды | 0,8 секунды |
| 10 000 PDF | 3,9 минуты | 46 секунд | 8 секунд |
| 100 000 PDF | 39 минут | 7,7 минуты | 80 секунд |
Для разовых скриптов, обрабатывающих несколько файлов, разница в скорости несущественна. Но для продакшен-конвейеров, обрабатывающих тысячи документов в день, разрыв между 39 минутами и 80 секундами меняет архитектурные решения.
Извлечение таблиц
Извлечение таблиц — главная причина, по которой разработчики выбирают pdfplumber вместо PyMuPDF. Именно здесь pdfplumber по-настоящему силён.
pdfplumber: структурированный разбор таблиц
pdfplumber предоставляет специализированное извлечение таблиц с настраиваемым распознаванием линий, объединением ячеек и визуальной отладкой:
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 возвращает структурированные данные строк/столбцов и обрабатывает объединённые ячейки, охватывающие заголовки и таблицы без рамок. Наложение визуальной отладки незаменимо для настройки параметров извлечения на сложных макетах.
PyMuPDF: базовое распознавание таблиц
PyMuPDF добавила распознавание таблиц в недавних версиях, но оно менее зрелое, чем алгоритмы 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)
Извлечение таблиц в PyMuPDF работает для простых сеточных таблиц с видимыми рамками. Оно с трудом справляется с макетами без рамок, многоуровневыми заголовками и ячейками, охватывающими несколько строк или столбцов, — именно с теми случаями, где pdfplumber сильнее всего.
PDF Oxide: вывод таблиц в Markdown
PDF Oxide преобразует таблицы в синтаксис Markdown в рамках своего конвейера структурированного вывода:
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)
Распознавание таблиц в PDF Oxide работает для стандартных сеточных макетов и создаёт чистый вывод в Markdown или HTML. Для сложных таблиц с объединёнными ячейками, дизайном без рамок или охватывающими заголовками специализированные алгоритмы pdfplumber остаются более надёжными.
Сводка по извлечению таблиц
| Возможность | pdfplumber | PyMuPDF | PDF Oxide |
|---|---|---|---|
| Простые таблицы с рамками | Да | Да | Да |
| Таблицы без рамок | Да | Ограниченно | Ограниченно |
| Объединённые ячейки | Да | Ограниченно | Ограниченно |
| Многоуровневые заголовки | Да | Нет | Нет |
| Настраиваемое распознавание | Да | Ограниченно | Нет |
| Визуальная отладка | Да | Нет | Нет |
| Формат вывода | Списки Python | DataFrame pandas | Markdown / HTML |
| Скорость | Медленно (чистый Python) | Быстро | Самая быстрая |
Если извлечение сложных таблиц — ваш единственный сценарий, pdfplumber — лучший инструмент. Если вам нужны таблицы вместе с быстрым извлечением текста, извлечением изображений или созданием PDF, PDF Oxide охватывает больше задач.
Извлечение текста
Для извлечения обычного текста обе библиотеки справляются с задачей, но различаются по скорости и устройству 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)
Все три дают сопоставимый текстовый вывод для корректно сформированных PDF. PDF Oxide достигает 99,5% совпадения текста с PyMuPDF на всём корпусе, а оставшиеся 0,5% различий приходятся на нормализацию пробелов и обработку лигатур.
Позиционирование на уровне символов
И pdfplumber, и PyMuPDF предоставляют данные о позициях на уровне символов, что важно для пространственного анализа, распознавания ограничивающих рамок и восстановления нестандартных макетов.
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 возвращает словари по каждому символу с богатыми метаданными. PyMuPDF возвращает вложенные структуры блок/строка/спан. PDF Oxide возвращает плоские объекты символов с данными о позиции и шрифте.
Лицензирование
Для коммерческих проектов это самое значимое различие между pdfplumber и PyMuPDF.
| pdfplumber | PyMuPDF | PDF Oxide | |
|---|---|---|---|
| Лицензия | MIT | AGPL-3.0 | MIT |
| Коммерческий продукт | Да | Требуется коммерческая лицензия | Да |
| Закрытый SaaS | Да | Требуется коммерческая лицензия | Да |
| Распространение через Docker | Да | Требуется коммерческая лицензия | Да |
| Внутренние инструменты | Да | Да | Да |
| Проект с открытым кодом | Да | Да (если совместим с AGPL) | Да |
Проблема AGPL у PyMuPDF
PyMuPDF оборачивает MuPDF, который лицензирован под AGPL-3.0. Если вы распространяете ПО, включающее PyMuPDF, — в том числе SaaS, веб-приложения и Docker-контейнеры, — ваш код должен быть открыт под AGPL, либо вы должны купить коммерческую лицензию у Artifex.
Artifex не публикует цены на коммерческие лицензии открыто. Для получения расчёта нужно связаться с их отделом продаж. Лицензии обычно выдаются на одно приложение, продлеваются ежегодно, без бесплатного уровня и без исключений для стартапов.
pdfplumber и PDF Oxide — обе под MIT
И pdfplumber, и PDF Oxide лицензированы под MIT. Используйте любую из них в любом проекте — коммерческом, проприетарном, SaaS или открытом — без каких-либо обязательств. Если лицензирование — ваш главный приоритет и вы выбираете между pdfplumber и PyMuPDF, то pdfplumber (или PDF Oxide) — более безопасный выбор.
Зашифрованные PDF
Обработка шифрования — значительный пробел в наборе функций pdfplumber и частая боль для разработчиков, работающих с документами, защищёнными паролем.
pdfplumber: нет поддержки шифрования
pdfplumber вообще не может открывать зашифрованные или защищённые паролем PDF. Если передать зашифрованный PDF в pdfplumber, он вызовет ошибку. Сначала нужно расшифровать файл другим инструментом:
import pdfplumber
# This will fail on encrypted PDFs:
with pdfplumber.open("encrypted.pdf") as pdf:
# raises pdfminer.pdfparser.PDFSyntaxError or similar
pass
Распространённый обходной путь — сначала расшифровать файл с помощью PyMuPDF или pypdf, а затем передать его в pdfplumber для извлечения таблиц, добавляя ещё одну зависимость в ваш конвейер.
PyMuPDF: полная поддержка шифрования
import fitz
doc = fitz.open("encrypted.pdf")
doc.authenticate("password")
page = doc[0]
text = page.get_text()
PyMuPDF поддерживает как пользовательские, так и владельческие пароли, шифрование AES-128 и AES-256 и может создавать зашифрованные PDF.
PDF Oxide: полная поддержка шифрования
from pdf_oxide import PdfDocument
doc = PdfDocument("encrypted.pdf", password="password")
text = doc.extract_text(0)
PDF Oxide обрабатывает все стандартные методы шифрования PDF (RC4, AES-128, AES-256) как для чтения, так и для записи. Не требуется дополнительных зависимостей или предобработки.
Извлечение изображений
Ещё один пробел в наборе функций pdfplumber. pdfplumber не извлекает встроенные изображения из 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"])
Если вашему конвейеру нужно извлекать из PDF и текст, и изображения, pdfplumber не справится с изображениями. Для этого нужны PyMuPDF, PDF Oxide или pypdfium2.
Вывод в Markdown и HTML
Ни pdfplumber, ни PyMuPDF не предоставляют встроенного преобразования в Markdown или HTML. Это уникальная возможность 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)
Для конвейеров LLM, систем RAG и процессов конвертации документов структурированный вывод в Markdown избавляет от отдельного шага преобразования. Пользователи PyMuPDF обычно полагаются на отдельный пакет pymupdf4llm, который в 69 раз медленнее встроенного преобразования PDF Oxide.
Когда выбирать каждую библиотеку
Выбирайте pdfplumber, если:
- Извлечение сложных таблиц — ваш основной сценарий. Алгоритмы таблиц pdfplumber обрабатывают объединённые ячейки, таблицы без рамок и охватывающие заголовки лучше любой другой Python-библиотеки.
- Вам нужна визуальная отладка. pdfplumber может рендерить размеченные изображения страниц, показывающие распознанные линии, символы и границы таблиц, — это незаменимо для настройки извлечения на сложных документах.
- Вам нужно решение на чистом Python. Никаких скомпилированных зависимостей, устанавливается везде, где работает Python.
- Скорость не важна. Если вы обрабатываете менее сотни файлов за раз, среднее значение 23ms вполне приемлемо.
Выбирайте PyMuPDF, если:
- У вас уже есть коммерческая лицензия MuPDF и вы зависите от специфичного для MuPDF рендеринга или экспорта в SVG.
- Вам нужен высококачественный рендеринг. Движок рендеринга MuPDF зрелый и хорошо справляется со сложными PDF.
- Ваш проект совместим с AGPL. Если вы создаёте ПО с открытым кодом под AGPL или совместимой лицензией, лицензирование PyMuPDF не проблема.
- Вам нужен OCR через Tesseract. PyMuPDF имеет встроенную интеграцию с Tesseract для отсканированных документов.
Выбирайте PDF Oxide, если:
- Вам нужны скорость и широкий набор функций. Среднее извлечение 0,8ms — в 5,8 раза быстрее PyMuPDF, в 29 раз быстрее pdfplumber — с текстом, изображениями, формами, созданием и шифрованием в одной библиотеке.
- Вы хотите лицензию MIT, не жертвуя скоростью. pdfplumber — MIT, но медленная. PyMuPDF быстрая, но AGPL. PDF Oxide и MIT, и быстрая.
- Вам нужен вывод в Markdown или HTML. Встроенное структурированное преобразование для конвейеров LLM и систем RAG.
- Вам нужна поддержка зашифрованных PDF под разрешительной лицензией. pdfplumber не справляется с шифрованием. PyMuPDF справляется, но требует соблюдения AGPL. PDF Oxide обрабатывает шифрование под MIT.
- Вам нужна одна библиотека для извлечения, создания и редактирования. И pdfplumber, и PyMuPDF требуют дополнительных инструментов для отдельных частей PDF-процесса. PDF Oxide охватывает извлечение, создание, редактирование, рендеринг и валидацию.
Используйте PDF Oxide + pdfplumber вместе:
Для конвейеров, которым нужно быстрое извлечение текста, извлечение изображений и разбор сложных таблиц, используйте PDF Oxide для общего конвейера и pdfplumber для таблиц:
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()
Установка
# pdfplumber
pip install pdfplumber
# PyMuPDF
pip install pymupdf
# PDF Oxide
pip install pdf_oxide
Все три устанавливаются через pip. pdfplumber и PDF Oxide лицензированы под MIT. PyMuPDF — под AGPL-3.0 — изучите последствия лицензирования, прежде чем добавлять её в коммерческий проект.
Вердикт
pdfplumber и PyMuPDF решают лишь части задачи. PDF Oxide решает её целиком.
| Что важно для вас | Лучший выбор |
|---|---|
| Максимальная скорость | PDF Oxide (0,8ms — в 29 раз быстрее pdfplumber) |
| Извлечение сложных таблиц | pdfplumber (визуальная отладка, объединённые ячейки) |
| Разрешительная лицензия + скорость | PDF Oxide — pdfplumber MIT, но медленная, PyMuPDF быстрая, но AGPL |
| Зашифрованные PDF | PDF Oxide или PyMuPDF — pdfplumber не умеет расшифровывать |
| Извлечение изображений | PDF Oxide или PyMuPDF — у pdfplumber нет поддержки изображений |
| Вывод в Markdown/HTML | PDF Oxide — единственная библиотека со встроенным преобразованием |
| OCR без Tesseract | PDF Oxide — встроенный PaddleOCR |
| Одна библиотека для всего | PDF Oxide — извлечение, создание, редактирование, шифрование, OCR |
Если только весь ваш процесс не сводится к извлечению сложных таблиц (таблицы без рамок, объединённые ячейки, визуальная отладка), PDF Oxide заменяет и pdfplumber, и PyMuPDF — быстрее, больше функций, лицензия MIT.
Начните за 10 секунд:
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
Связанные страницы
- PDF Oxide vs PyMuPDF — подробное сравнение с руководством по миграции
- PDF Oxide vs pdfplumber — подробное сравнение с примерами кода
- vs Python PDF-библиотеки — сравнение всех Python-библиотек
- Бенчмарки производительности — полная методика бенчмарка на корпусе
- Извлечение таблиц из PDF — руководство по извлечению таблиц
- Начало работы с Python — установка и первое извлечение