Skip to content

PyMuPDF vs pypdf — 어떤 Python PDF 라이브러리를 써야 할까?

PyMuPDF와 pypdf는 가장 인기 있는 두 Python PDF 라이브러리지만, 둘 다 상당한 트레이드오프가 있습니다. PyMuPDF는 빠르지만 AGPL-3.0 라이선스에 묶여 있습니다. pypdf는 관대한 라이선스를 갖지만 15배 느립니다. 이 페이지는 둘을 정면으로 비교하고, 왜 PDF Oxide가 둘 중 어느 쪽보다도 더 나은 선택인지를 보여줍니다.

짧게 답하자면: PDF Oxide는 PyMuPDF보다 5.8배, pypdf보다 15배 빠르며, MIT 라이선스이고, 두 라이브러리보다 더 많은 기능을 갖추고 있습니다 — 내장 Markdown/HTML 출력, XFA 폼 지원, 시스템 의존성이 없는 OCR을 포함합니다.

빠른 비교

PyMuPDF pypdf PDF Oxide
라이선스 AGPL-3.0 BSD-3 MIT
언어 C (MuPDF) 순수 Python Rust + PyO3
평균 추출 시간 4.6ms 12.1ms 0.8ms
p99 추출 시간 28ms 97ms 9ms
통과율 (3,830개 PDF) 99.3% 98.4% 100%
텍스트 추출 지원 지원 지원
문자 위치 지원 부분 지원 지원
이미지 추출 지원 지원 지원
폼 필드 읽기 + 쓰기 읽기 + 쓰기 읽기 + 쓰기
PDF 생성 지원 제한적 (병합만) 지원 (Markdown/HTML)
Markdown 출력 미지원 미지원 지원
HTML 출력 미지원 미지원 지원
렌더링 지원 미지원 지원
OCR Tesseract 미지원 내장 (PaddleOCR)
설치 크기 약 20 MB 약 1 MB 약 5 MB
암호화 읽기 + 쓰기 읽기 + 쓰기 읽기 + 쓰기
검색 지원 미지원 정규식 + 공간 검색
Python 버전 3.8–3.12 3.6+ 3.8–3.14

PyMuPDF는 pypdf보다 빠르고 기능도 풍부하지만, AGPL 라이선스는 많은 상업 프로젝트에서 받아들이기 어려운 걸림돌입니다. pypdf는 더 가볍고 BSD 라이선스지만, 상당히 느리고 추출 기능도 더 제한적입니다. PDF Oxide는 네이티브 엔진의 속도 이점과 관대한 라이선스의 자유로움을 결합합니다.

라이선스: AGPL vs BSD vs MIT

PyMuPDF와 pypdf 사이의 라이선스 차이는 둘 중 하나를 선택하는 팀에게 종종 결정적인 요인이 됩니다.

PyMuPDF — AGPL-3.0

PyMuPDF는 MuPDF를 래핑하며, MuPDF는 AGPL-3.0으로 라이선스되어 있습니다. 이는 강한 카피레프트 라이선스입니다. PyMuPDF를 사용하는 어떤 소프트웨어든 배포한다면 — SaaS 애플리케이션, Docker 컨테이너, 웹 서비스, 데스크톱 앱, CLI 도구를 포함하여 — 애플리케이션 전체를 AGPL-3.0으로 공개해야 합니다. 즉, 전체 소스 코드를 동일한 라이선스로 공개해야 한다는 뜻입니다.

대안은 MuPDF의 배후 회사인 Artifex에서 상업용 라이선스를 구매하는 것입니다. Artifex는 가격을 공개적으로 게시하지 않으므로 견적을 받으려면 영업팀에 문의해야 합니다. 상업용 라이선스는 일반적으로 연 단위이며 애플리케이션별로 가격이 책정됩니다.

AGPL이 영향을 미치는 경우:

  • PyMuPDF를 포함한 제품을 출시하는 경우 (데스크톱 앱, 모바일 앱, Electron)
  • PyMuPDF로 PDF를 처리하는 SaaS 또는 웹 서비스를 운영하는 경우
  • PyMuPDF가 포함된 Docker 이미지를 배포하는 경우
  • 내부적으로 PyMuPDF를 사용하는 API를 제공하는 경우

AGPL이 영향을 미치지 않는 경우:

  • 프로젝트가 이미 AGPL 호환 라이선스로 오픈소스화된 경우
  • PyMuPDF를 절대 배포되지 않는 내부 도구에만 사용하는 경우

pypdf — BSD-3

pypdf는 관대한 BSD 3-Clause 라이선스를 사용합니다. 코드를 오픈소스화할 의무 없이 상업용 제품, 비공개 소스 소프트웨어, SaaS 애플리케이션에서 pypdf를 사용할 수 있습니다. 유일한 요건은 재배포 시 저작권 고지를 유지하는 것입니다.

PDF Oxide — MIT

PDF Oxide는 MIT 라이선스입니다 — 가장 관대한 일반적인 오픈소스 라이선스입니다. 라이선스 텍스트를 포함하는 것 외에 어떤 제약도 없이 모든 맥락(상업용, 독점, SaaS, 오픈소스)에서 사용하세요.

라이선스 요약

사용 사례 PyMuPDF (AGPL) pypdf (BSD) PDF Oxide (MIT)
상업용 제품 라이선스 필요 가능 가능
비공개 소스 SaaS 라이선스 필요 가능 가능
Docker 배포 라이선스 필요 가능 가능
내부 도구 가능 가능 가능
오픈소스 (AGPL 호환) 가능 가능 가능
오픈소스 (MIT/BSD/Apache) 불가 가능 가능

라이선스 준수가 중요한 상업 프로젝트의 경우 pypdf와 PDF Oxide 모두 안전한 선택입니다. PyMuPDF는 애플리케이션을 오픈소스화하거나 상업용 라이선스를 구매하는 것 중 하나를 요구합니다.

속도 벤치마크

모든 벤치마크는 동일한 3,830개 PDF 코퍼스에서 실행되었습니다 — 세 개의 독립적이고 공개적으로 이용 가능한 테스트 스위트(veraPDF, Mozilla pdf.js, DARPA SafeDocs)로 구성되며, 모든 PDF 사양 버전(1.0–2.0), 암호화된 파일, CJK 인코딩, 복잡한 레이아웃, 손상된 문서를 포괄합니다.

텍스트 추출 속도

라이브러리 평균 p99 PDF Oxide 대비
PDF Oxide 0.8ms 9ms 1x
PyMuPDF 4.6ms 28ms 5.8x 느림
pypdf 12.1ms 97ms 15.1x 느림

PyMuPDF는 파싱을 MuPDF의 C 엔진에 위임하기 때문에 pypdf보다 2.6x 빠릅니다. pypdf는 모든 것을 순수 Python에서 수행합니다 — 파싱, 폰트 디코딩, 텍스트 조립 — 이는 모든 연산이 인터프리터 오버헤드를 치른다는 의미입니다.

PDF Oxide가 둘 다보다 빠른 이유는 Rust 코어가 모든 PDF 파싱, 폰트 디코딩, 텍스트 레이아웃을 PyO3를 통해 네이티브로 처리하고, 최종 결과만 Python 경계를 넘기 때문입니다. 서브프로세스 오버헤드도, ctypes를 통한 C 라이브러리 브리징도, 인터프리터 병목도 없습니다.

신뢰성

라이브러리 통과한 유효 PDF 통과율
PDF Oxide 3,823 / 3,823 100%
PyMuPDF 3,796 / 3,823 99.3%
pypdf 3,762 / 3,823 98.4%

PyMuPDF는 코퍼스의 27개 유효 PDF에서 실패합니다. pypdf는 61개에서 실패합니다. 두 경우 모두, 이들은 라이브러리가 충돌하거나 빈/잘못된 텍스트를 반환하는 유효한 PDF 파일입니다. PDF Oxide는 3,823개 유효 PDF 전체를 실패 없이 처리합니다.

전체 3,830개 파일 코퍼스에서 통과하지 못한 7개 파일은 의도적으로 손상시킨 테스트 픽스처(누락된 PDF 헤더, 퍼즈로 손상된 카탈로그, 잘못된 xref 스트림)이며, 모든 라이브러리에 대해 통과율 계산에서 제외됩니다.

실무적으로 이것이 의미하는 바

매일 수천 개의 PDF를 처리하는 파이프라인의 경우, PyMuPDF의 99.3% 통과율은 1,000개 문서당 약 7건의 실패를 의미합니다. pypdf의 98.4%는 1,000개당 16건의 실패를 의미합니다. 이들은 폴백 로직, 수동 검토로 처리하거나, 아니면 그냥 손실된 데이터로 받아들여야 하는 문서입니다.

테스트 코퍼스에서 PDF Oxide의 100% 통과율은 프로덕션에서 다뤄야 할 엣지 케이스가 더 적다는 것을 의미합니다.

기능 비교

텍스트 추출

세 라이브러리 모두 기본 텍스트 추출을 지원합니다. API 스타일은 다릅니다:

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")
text = reader.pages[0].extract_text()
print(text)

PDF Oxide:

from pdf_oxide import PdfDocument

doc = PdfDocument("report.pdf")
text = doc.extract_text(0)
print(text)

PyMuPDF는 페이지 객체 모델을 사용합니다(doc[0]이 페이지를 반환). pypdf는 reader/pages 패턴을 사용합니다. PDF Oxide는 페이지 인덱스를 직접 사용합니다.

문자 수준 추출(위치, 폰트 크기, 경계 상자)의 경우, PyMuPDF는 중첩된 딕셔너리 구조를 반환하는 get_text("dict")를 제공합니다. pypdf는 부분적인 문자 위치 데이터를 제공합니다. PDF Oxide는 문자별 경계 상자와 폰트 메타데이터를 갖춘 extract_chars()를 제공합니다.

Markdown 변환

이것은 중요한 차별점입니다. 많은 LLM 및 RAG 파이프라인은 PDF로부터의 Markdown 출력을 필요로 합니다.

PyMuPDF:

# PyMuPDF has no built-in Markdown conversion.
# You need pymupdf4llm, a separate package:
import pymupdf4llm

md = pymupdf4llm.to_markdown("paper.pdf")

pymupdf4llm은 동작하지만 PDF Oxide의 내장 Markdown 변환보다 69x 느립니다(평균 55.5ms 대 0.8ms). 또한 자체 유지보수 주기를 가진 별도의 의존성이기도 합니다.

pypdf:

# pypdf has no Markdown conversion.
# You would need an external tool chain (e.g., extract text,
# then use a separate library to structure it as Markdown).

PDF Oxide:

from pdf_oxide import PdfDocument

doc = PdfDocument("paper.pdf")
md = doc.to_markdown(0, detect_headings=True)
print(md)

PDF Oxide의 Markdown 변환은 내장되어 있으며, 제목 감지를 처리하고, 표 구조를 보존하며, 일반 텍스트 추출과 동일한 속도로 실행됩니다.

HTML 변환

PyMuPDF: 내장 HTML 출력 없음.

pypdf: HTML 출력 없음.

PDF Oxide:

from pdf_oxide import PdfDocument

doc = PdfDocument("paper.pdf")
html = doc.to_html(0)
print(html)

폼 필드

세 라이브러리 모두 폼 필드(AcroForm)의 읽기와 쓰기를 지원합니다.

PyMuPDF:

import fitz

doc = fitz.open("form.pdf")
page = doc[0]
for widget in page.widgets():
    print(f"{widget.field_name}: {widget.field_value}")

pypdf:

from pypdf import PdfReader

reader = PdfReader("form.pdf")
fields = reader.get_fields()
for name, field in fields.items():
    print(f"{name}: {field.get('/V', '')}")

PDF Oxide:

from pdf_oxide import PdfDocument

doc = PdfDocument("form.pdf")
fields = doc.get_form_fields()
for field in fields:
    print(f"{field.name}: {field.value}")

한 가지 주목할 만한 차이: PDF Oxide는 XFA 폼(XML Forms Architecture)을 지원하는데, 이는 많은 정부 및 기업 PDF 폼에서 사용됩니다. PyMuPDF도 pypdf도 XFA 폼 데이터 추출을 처리하지 못합니다.

이미지 추출

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 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의 접근 방식은 두 단계의 xref 조회를 필요로 합니다. pypdf와 PDF Oxide는 더 간결한 API를 제공합니다.

렌더링

PyMuPDF는 MuPDF의 렌더링 엔진을 사용하여 PDF 페이지를 이미지(PNG, JPEG)로 렌더링할 수 있습니다. pypdf는 페이지를 전혀 렌더링하지 못합니다. PDF Oxide는 내장 렌더링 엔진을 포함합니다.

OCR

PyMuPDF는 스캔된 PDF의 OCR을 위해 Tesseract와 통합됩니다. pypdf는 OCR을 지원하지 않습니다. PDF Oxide는 PaddleOCR을 통한 내장 OCR을 갖추고 있으며, 외부 시스템 의존성이 필요 없습니다.

PDF 생성

PyMuPDF는 PDF를 생성할 수 있지만 페이지 위에 텍스트, 이미지, 도형을 수동으로 배치해야 합니다 — 구조화된 콘텐츠로부터 PDF를 생성하는 고수준 API가 없습니다.

pypdf는 PDF를 처음부터 생성할 수 없습니다. 기존 PDF를 병합, 분할, 수정할 수는 있지만, 생성을 위해서는 reportlab이나 fpdf2 같은 별도 라이브러리가 필요합니다.

PDF Oxide는 Markdown 또는 HTML로부터 PDF를 생성할 수 있습니다:

from pdf_oxide import Pdf

pdf = Pdf.from_markdown("# Invoice\n\n| Item | Price |\n|------|-------|\n| Widget | $9.99 |")
pdf.save("invoice.pdf")

암호화

세 라이브러리 모두 암호화된 PDF 읽기와 암호화된 출력 쓰기를 지원합니다.

PyMuPDF:

import fitz

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

pypdf:

from pypdf import PdfReader

reader = PdfReader("encrypted.pdf")
reader.decrypt("password")
text = reader.pages[0].extract_text()

PDF Oxide:

from pdf_oxide import PdfDocument

doc = PdfDocument("encrypted.pdf", password="password")
text = doc.extract_text(0)

기능 요약

기능 PyMuPDF pypdf PDF Oxide
텍스트 추출 지원 지원 지원
문자 위치 지원 부분 지원 지원
이미지 추출 지원 지원 지원
폼 필드 (AcroForm) 읽기 + 쓰기 읽기 + 쓰기 읽기 + 쓰기
XFA 폼 미지원 미지원 지원
PDF 생성 수동 미지원 Markdown/HTML
Markdown 출력 미지원 (pymupdf4llm) 미지원 내장
HTML 출력 미지원 미지원 내장
렌더링 지원 미지원 지원
OCR Tesseract 미지원 내장 (PaddleOCR)
검색 지원 미지원 정규식 + 공간 검색
암호화 읽기 + 쓰기 읽기 + 쓰기 읽기 + 쓰기
PDF/A 검증 미지원 미지원 지원
SVG 내보내기 지원 미지원 미지원
병합/분할 지원 지원 지원

각 라이브러리를 선택해야 할 때

pypdf를 선택하세요, 만약:

  • 컴파일된 C나 Rust 확장이 없는 순수 Python 솔루션이 필요한 경우
  • 단순한 PDF 조작(병합, 분할, 회전, 암호화/복호화)을 하는 경우
  • 사용 사례에서 속도가 중요하지 않은 경우
  • 가능한 한 작은 설치 용량(약 1 MB)을 원하는 경우
  • 폭넓은 Python 버전 지원(3.6+)이 필요한 경우

PyMuPDF를 선택하세요, 만약:

  • 이미 Artifex로부터 MuPDF 상업용 라이선스를 보유한 경우
  • PDF 페이지로부터 SVG 내보내기가 필요한 경우
  • 프로젝트가 이미 AGPL-3.0으로 라이선스된 경우
  • MuPDF 특유의 렌더링 동작에 의존하는 경우

PDF Oxide를 선택하세요, 만약:

  • 최대 텍스트 추출 속도가 필요한 경우(PyMuPDF보다 5.8x, pypdf보다 15x 빠름)
  • 상업용 또는 비공개 소스 용도로 MIT 라이선스를 원하는 경우
  • LLM/RAG 파이프라인을 위한 내장 Markdown 또는 HTML 출력이 필요한 경우
  • XFA 폼 지원이 필요한 경우
  • 외부 시스템 의존성 없는 내장 OCR을 원하는 경우
  • 유효한 PDF에서 100% 신뢰성을 원하는 경우

설치

# PyMuPDF
pip install pymupdf

# pypdf
pip install pypdf

# PDF Oxide
pip install pdf_oxide

셋 다 pip를 통해 사용할 수 있습니다. PyMuPDF는 MuPDF를 번들로 포함한 약 20 MB 휠을 배포합니다. pypdf는 약 1 MB의 순수 Python입니다. PDF Oxide는 Linux(x86_64, aarch64), macOS(x86_64, arm64), Windows(x86_64)용 사전 빌드된 휠(약 5 MB)을 배포합니다.

결론

PyMuPDF와 pypdf 사이에서 고르고 있다면, 속도와 라이선스 자유 사이에서 고르고 있는 것입니다. PDF Oxide는 둘 다 제공합니다 — PyMuPDF보다 빠르고, pypdf보다 관대하며, 어느 라이브러리도 제공하지 않는 기능을 갖췄습니다.

당신에게 중요한 것 최선의 선택
최대 속도 PDF Oxide (0.8ms)
관대한 라이선스 PDF Oxide (MIT) 또는 pypdf (BSD)
속도 + 관대한 라이선스 PDF Oxide — 유일한 선택지
Markdown/HTML 출력 PDF Oxide — 내장
XFA 폼 PDF Oxide — 이를 지원하는 유일한 라이브러리
100% 신뢰성 PDF Oxide — 100% 통과율
Tesseract 없는 OCR PDF Oxide — 내장 PaddleOCR
SVG 내보내기 PyMuPDF
순수 Python, 바이너리 없음 pypdf

10초 만에 시작하기:

pip install pdf_oxide
from pdf_oxide import PdfDocument

doc = PdfDocument("report.pdf")
text = doc.extract_text(0)

관련 페이지