Skip to content

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
Частка успішних (3830 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

Бенчмарки швидкості

Усі три бібліотеки протестовано на одному й тому самому корпусі з 3830 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% (3777/3823) 99,3% (3796/3823) 100% (3823/3823)

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 секунди
1000 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

Пов’язані сторінки