Найкраща 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 %. Сім файлів із корпусу 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