Skip to content

Миграция с PyMuPDF (fitz) на PDF Oxide

Полное руководство по переходу с PyMuPDF на PDF Oxide: все API, которыми вы пользуетесь сегодня, и их замены.

Зачем уходить с PyMuPDF?

Четыре веские причины для миграции:

  1. В 5,8× быстрее — PDF Oxide в среднем обрабатывает страницу за 0,8 мс против 4,6 мс у PyMuPDF. На объёме разница накапливается: пакет из 1 000 страниц завершается меньше чем за секунду, а не за пять.
  2. Лицензия MIT — PyMuPDF распространяется под AGPL, которая обязывает открывать исходники любого кода, взаимодействующего с ней, или покупать коммерческую лицензию. PDF Oxide под MIT — применяйте где угодно без оговорок.
  3. Надёжность 100 % — PDF Oxide проходит 100 % тестового набора PDF. PyMuPDF срывается на 0,7 % файлов (99,3 % успеха) — это примерно один сломанный результат на каждые 140 документов.
  4. Функции «из коробки» — конвертация в Markdown, вывод HTML, OCR, поддержка XFA-форм и рендеринг PDF включены. PyMuPDF для того же требует отдельные пакеты (pymupdf4llm) или внешние инструменты (Tesseract).

Шаг 1. Установка

pip install pdf_oxide
pip uninstall pymupdf  # опционально — удалите, когда будете готовы

Шаг 2. Замените импорты

# До
import fitz

# После
from pdf_oxide import PdfDocument

Если для Markdown использовался pymupdf4llm, эту зависимость можно полностью убрать — PDF Oxide поддерживает Markdown нативно.

Шаг 3. Таблица соответствия API

Задача PyMuPDF PDF Oxide
Открыть PDF fitz.open("file.pdf") PdfDocument("file.pdf")
Количество страниц doc.page_count doc.page_count()
Извлечь текст doc[0].get_text() doc.extract_text(0)
Позиции символов doc[0].get_text("dict") doc.extract_chars(0)
Извлечь изображения doc[0].get_images() + doc.extract_image(xref) doc.extract_images(0)
Поиск текста doc[0].search_for("query") doc.search_page(0, "query")
Поля форм doc[0].widgets() или doc.get_form_fields() doc.get_form_fields()
Зашифрованный PDF doc.authenticate("pw") PdfDocument("f.pdf", password="pw")
В Markdown pymupdf4llm.to_markdown("file.pdf") (отдельный пакет) doc.to_markdown(0) (встроено)
В HTML Недоступно doc.to_html(0)
Создать PDF Ручной insert_text() Pdf.from_markdown("# Заголовок")
Рендер в изображение doc[0].get_pixmap() doc.render_page(0)
XFA-формы Не поддерживаются doc.has_xfa()
OCR Требуется Tesseract Встроенный PaddleOCR

Шаг 4. Типичные изменения паттернов

Цикл извлечения текста

# PyMuPDF
import fitz
doc = fitz.open("report.pdf")
for page in doc:
    text = page.get_text()
    print(text)

# PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
for i in range(doc.page_count()):
    text = doc.extract_text(i)
    print(text)

Извлечение изображений

PyMuPDF требует многошагового обхода через xref. PDF Oxide делает это за один вызов:

# PyMuPDF — многошаговый поиск через xref
import fitz
doc = fitz.open("report.pdf")
page = doc[0]
for img in page.get_images():
    xref = img[0]
    base = doc.extract_image(xref)
    with open(f"img.{base['ext']}", "wb") as f:
        f.write(base["image"])

# PDF Oxide — один шаг
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
for i, img in enumerate(doc.extract_image_bytes(0)):
    with open(f"img_{i}.{img['format']}", "wb") as f:
        f.write(img["data"])

Зашифрованные PDF

В PyMuPDF принят двухшаговый паттерн «открыть, затем аутентифицироваться». PDF Oxide поддерживает и password= в конструкторе, и вызов doc.authenticate() после открытия:

# PyMuPDF
import fitz
doc = fitz.open("encrypted.pdf")
doc.authenticate("password")
text = doc[0].get_text()

# PDF Oxide — один шаг с password=
from pdf_oxide import PdfDocument
doc = PdfDocument("encrypted.pdf", password="password")
text = doc.extract_text(0)

Конвертация в Markdown

PyMuPDF требует отдельный пакет pymupdf4llm. В PDF Oxide Markdown встроен:

# PyMuPDF — нужен дополнительный пакет
import pymupdf4llm
md = pymupdf4llm.to_markdown("report.pdf")

# PDF Oxide — встроено
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
md = doc.to_markdown(0)

Рендеринг страниц

# PyMuPDF
import fitz
doc = fitz.open("report.pdf")
pix = doc[0].get_pixmap()
pix.save("page.png")

# PDF Oxide
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
png_bytes = doc.render_page(0, dpi=150)
with open("page.png", "wb") as f:
    f.write(png_bytes)

Шаг 5. Проверка миграции

Прогоните свои тестовые файлы через обе библиотеки и сравните вывод:

from pdf_oxide import PdfDocument

doc = PdfDocument("your-test-file.pdf")

# Проверка извлечения текста
text = doc.extract_text(0)
print(text[:500])

# Проверка количества страниц
print(f"Pages: {doc.page_count()}")

# Проверка полей форм (если есть)
fields = doc.get_form_fields()
for f in fields:
    print(f"{f.name}: {f.value}")

Другие руководства по миграции

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