Skip to content

pdfplumber vs PyMuPDF — 속도, 표, 라이선스

pdfplumber와 PyMuPDF는 인기 있는 Python PDF 라이브러리이지만, 둘 다 절충을 강요합니다. pdfplumber는 표 처리에 뛰어나지만 필요 이상으로 29배 느립니다. PyMuPDF는 빠르지만 상업적 사용을 막는 AGPL-3.0 라이선스에 묶여 있습니다. 이 페이지에서는 두 라이브러리를 비교하고, 대부분의 사용 사례에서 PDF Oxide가 더 나은 선택인 이유를 보여줍니다.

짧은 결론: PDF Oxide는 pdfplumber보다 29배, PyMuPDF보다 5.8배 빠르며, 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

속도 벤치마크

세 라이브러리 모두 세 개의 독립적인 공개 테스트 스위트(veraPDF, Mozilla pdf.js, DARPA SafeDocs)에서 수집한 동일한 3,830개 PDF 코퍼스로 벤치마크했습니다. 이 코퍼스는 모든 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배 느림 1배
통과율(유효 PDF) 98.8%(3,777/3,823) 99.3%(3,796/3,823) 100%(3,823/3,823)

PyMuPDF는 모든 파싱을 MuPDF C 라이브러리에 위임하기 때문에 pdfplumber보다 약 5배 빠릅니다. pdfplumber는 파싱에 pdfminer를 사용한 뒤 자체 공간 분석 레이어를 추가하는데, 둘 다 순수 Python으로 작성되어 있습니다. PDF Oxide는 모든 파싱, 폰트 디코딩, 텍스트 조립을 PyO3를 통해 Python 프로세스 안에서 직접 실행되는 컴파일된 Rust로 처리하며, 이것이 PyMuPDF 대비 5.8배, pdfplumber 대비 29배의 우위를 만듭니다.

이 수치가 실제로 의미하는 것

작업량 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초의 격차가 아키텍처 결정을 바꿉니다.

표 추출

표 추출은 개발자가 PyMuPDF 대신 pdfplumber를 선택하는 주된 이유입니다. 바로 이 부분에서 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 리스트 pandas DataFrame 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는 전체 코퍼스에서 PyMuPDF와 99.5%의 텍스트 일치율을 달성하며, 나머지 0.5%의 차이는 공백 정규화와 합자(ligature) 처리에서 발생합니다.

문자 단위 위치 지정

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 호환 시) 가능

PyMuPDF의 AGPL 문제

PyMuPDF는 AGPL-3.0 라이선스인 MuPDF를 감싸고 있습니다. 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에 의존하는데, 이는 PDF Oxide의 내장 변환보다 69배 느립니다.

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

다음 경우 pdfplumber를 선택하세요:

  • 복잡한 표 추출이 주된 사용 사례인 경우. pdfplumber의 표 알고리즘은 병합된 셀, 테두리 없는 표, 걸친 헤더를 다른 어떤 Python 라이브러리보다 잘 처리합니다.
  • 시각적 디버깅이 필요한 경우. pdfplumber는 감지된 선·문자·표 경계를 보여주는 주석이 달린 페이지 이미지를 렌더링할 수 있어, 까다로운 문서에서 추출을 조정할 때 매우 유용합니다.
  • 순수 Python 솔루션을 원하는 경우. 컴파일된 의존성이 없어, Python이 실행되는 곳이라면 어디서든 설치됩니다.
  • 속도가 문제되지 않는 경우. 한 번에 백 개 미만의 파일을 처리한다면 평균 23ms는 충분히 허용 가능합니다.

다음 경우 PyMuPDF를 선택하세요:

  • 이미 상업용 MuPDF 라이선스를 보유하고 있고 MuPDF 고유의 렌더링이나 SVG 내보내기에 의존하는 경우.
  • 고품질 렌더링이 필요한 경우. MuPDF의 렌더링 엔진은 성숙하며 복잡한 PDF를 잘 처리합니다.
  • 프로젝트가 AGPL과 호환되는 경우. AGPL 또는 호환 라이선스 하에 오픈소스 소프트웨어를 구축한다면 PyMuPDF의 라이선스는 문제되지 않습니다.
  • Tesseract를 통한 OCR이 필요한 경우. PyMuPDF는 스캔된 문서를 위한 Tesseract 통합을 내장하고 있습니다.

다음 경우 PDF Oxide를 선택하세요:

  • 속도와 폭넓은 기능 범위가 필요한 경우. 평균 0.8ms 추출 — PyMuPDF보다 5.8배, pdfplumber보다 29배 빠르며 — 텍스트, 이미지, 폼, 생성, 암호화를 하나의 라이브러리에서 제공합니다.
  • 속도를 희생하지 않고 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 — pdfplumber보다 29배 빠름)
복잡한 표 추출 pdfplumber(시각적 디버깅, 병합된 셀)
관대한 라이선스 + 속도 PDF Oxide — pdfplumber는 MIT이지만 느리고, PyMuPDF는 빠르지만 AGPL
암호화된 PDF PDF Oxide 또는 PyMuPDF — pdfplumber는 복호화 불가
이미지 추출 PDF Oxide 또는 PyMuPDF — pdfplumber는 이미지 미지원
Markdown/HTML 출력 PDF Oxide — 내장 변환을 갖춘 유일한 라이브러리
Tesseract 없는 OCR 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

관련 페이지