Lightweight Document Parser - 순수 Python으로 PDF, DOCX, PPTX, HWPX 파싱
Project description
LitParser
Lightweight Document Parser — 순수 Python 문서 파서
외부 라이브러리 의존성 없이 PDF, DOCX, PPTX, XLSX, HWP 등 다양한 문서 포맷에서 텍스트, 표, 이미지를 추출합니다.
왜 LitParser인가?
기존 PDF 파서들의 한계:
| 라이브러리 | 라이선스 | 의존성 | 한국어 | 2단 레이아웃 |
|---|---|---|---|---|
| PyMuPDF | AGPL / 상용 듀얼 | C 바이너리 | △ | △ |
| pdfplumber | MIT | pdfminer 의존 | △ | ✗ |
| PyPDF | BSD | 없음 | △ | ✗ |
| LitParser | AGPL / 상용 듀얼 | 없음 | ✓ | ✓ |
LitParser는 순수 Python으로 PDF 스펙을 직접 파싱하여, C 라이브러리 없이도 PyMuPDF에 근접한 텍스트 추출 품질을 제공합니다.
설치
pip install litparser
Python 3.8+ 지원. 외부 의존성 없음.
빠른 시작
from litparser import parse
# 자동 포맷 감지 — PDF, DOCX, PPTX, XLSX, HWP 등
result = parse('document.pdf')
# 텍스트
print(result.text)
# 표 (마크다운)
for table in result.tables:
print(table['markdown'])
# 이미지 (base64)
result = parse('document.pdf', include_images=True)
for img in result.images:
print(f"Page {img['page']}, {img['width']}x{img['height']}")
CLI 사용
litparser document.pdf # 텍스트 출력
litparser document.pdf --markdown # 마크다운 변환
litparser document.pdf --json --o ./result.json # JSON 출력
litparser document.pdf --info # 문서 정보
PDF 전용 API
from litparser import parse_pdf, extract_text, extract_tables, extract_images
doc = parse_pdf('paper.pdf')
# 페이지별 텍스트
text = extract_text(doc, page_num=0)
# 표 추출
tables = extract_tables(doc, page_num=0)
for t in tables:
print(t.to_markdown())
# 이미지 추출
images = extract_images(doc, page_num=0)
지원 포맷
| 포맷 | Modern | Legacy |
|---|---|---|
| Word | .docx ✅ | .doc ✅ |
| PowerPoint | .pptx ✅ | .ppt ✅ |
| Excel | .xlsx ✅ | .xls ✅ |
| 한글 | .hwpx ✅ | .hwp ✅ |
| .pdf ✅ | - | |
| 텍스트 | .txt, .md ✅ | - |
핵심 기능
텍스트 추출
- 2단 학술논문 레이아웃 자동 감지 및 올바른 읽기 순서 출력
- 수식 추출 —
˜y∗ = arg max w·1[a =a]등 유니코드 텍스트로 추출 - 한국어 자간 복원 — "해 설 서" → "해설서" 자동 교정
- 윗첨자/아래첨자 인식 및 본문에 자연스럽게 합침
- 리거처(fi, fl, ffi) 분리 복원
- Figure 내부 텍스트 추출 (Form XObject 재귀 파싱)
표 추출
4단계 감지 파이프라인으로 다양한 표 구조를 처리합니다:
- Grid 감지 — 수평선 + 수직선이 모두 있는 정형 표
- HLine 감지 — 수평선만 있는 borderless 표
- Numeric Data 감지 — 숫자 데이터 패턴 기반 (선 없는 학술 표)
- Alignment 감지 — x좌표 정렬 기반 (완전히 선 없는 표)
tables = extract_tables(doc, page_num=0)
for t in tables:
print(f"{t.rows}x{t.cols} ({t.method})")
print(t.to_markdown())
이미지 추출
- Form XObject 재귀 탐색으로 중첩된 이미지까지 추출
- FlateDecode → PNG 자동 변환
- DCTDecode(JPEG), JPXDecode(JPEG2000) 지원
- base64 인코딩 포함
레이아웃 분석
- 라인 시작점(x0) 히스토그램 기반 2단 감지
- 제목, 저자 등 full-width 영역 자동 분리
- 표 영역을 칼럼 감지에서 제외하여 오탐 방지
- 코드 블록, 수식 들여쓰기 내성 (noise threshold 15%)
아키텍처
litparser/
├── __init__.py # 통합 API, 텍스트 추출, 후처리
├── _grid_table.py # 표 감지 (grid, hline, alignment, numeric)
├── core/
│ ├── parser.py # PDF 파서 (xref, 객체, 스트림)
│ ├── content_stream.py # 콘텐츠 스트림 → 텍스트 아이템
│ ├── table_detector.py # 표 감지 오케스트레이터
│ ├── layout_analyzer.py # 2단 레이아웃, 읽기 순서
│ ├── image_extractor.py # 이미지 추출, 변환
│ └── stream_decoder.py # FlateDecode, LZW, ASCII85 등
└── formats/
├── docx_parser.py # Word .docx
├── doc_parser.py # Word .doc (OLE)
├── pptx_parser.py # PowerPoint .pptx
├── xlsx_parser.py # Excel .xlsx
├── hwpx_parser.py # 한글 .hwpx
└── hwp_parser.py # 한글 .hwp (OLE)
벤치마크
arXiv 2단 논문 3종 + 한국어 행정문서 2종, 총 5개 PDF 기준.
읽기 순서 정확도
2단 학술논문에서 "Abstract → Introduction", "제목 → 저자 → 본문" 등 12개 순서 체크:
| 파서 | 정확도 |
|---|---|
| LitParser | 75% |
| PyMuPDF | 83% |
| PyPDF | 83% |
| pdfplumber | 25% |
PyMuPDF/PyPDF는 줄 단위 출력이라 단순 순서 체크에서 유리하지만, 실제 문맥을 읽을 때는 좌→우 행 단위 출력이 2단 내용을 섞습니다. LitParser는 좌칼럼→우칼럼 순서로 문맥이 자연스럽습니다.
표 감지
| 문서 | LitParser | PyMuPDF | pdfplumber |
|---|---|---|---|
| T3RL (12p, 2단) | 3 (실제 표만) | 12 | 21 |
| ICRL (11p, 2단) | 7 | 7 | 8 |
| RLM (38p, 2단) | 2 | 3 | 16 |
LitParser는 Figure 캡션, 코드 블록 등의 FP(False Positive)를 필터링하여 실제 데이터 표만 추출합니다.
속도
| 문서 | LitParser | PyMuPDF | pdfplumber | PyPDF |
|---|---|---|---|---|
| T3RL (12p) | 958ms | 97ms | 1,898ms | 493ms |
| ICRL (11p) | 683ms | 79ms | 1,494ms | 403ms |
| RLM (38p) | 1,619ms | 199ms | 3,944ms | 972ms |
PyMuPDF(C 바이너리)보다 5~10배 느리지만, pdfplumber보다 2배 빠릅니다. 순수 Python 구현 대비 합리적인 성능입니다.
로드맵
- 수식 LaTeX 원본 복원 (현재 유니코드 텍스트로 추출)
- Tagged PDF (StructTree) 활용 강화
- OCR 연동 (scanned PDF)
- 벤치마크 자동화 및 논문
라이선스
LitParser는 듀얼 라이선스로 제공됩니다.
AGPL-3.0 (오픈소스)
- 오픈소스 프로젝트에서 자유롭게 사용 가능
- 네트워크 서비스(SaaS 등)로 제공 시 전체 소스코드를 AGPL-3.0으로 공개 필요
상용 라이선스
- 소스코드 공개 없이 상업적 사용 가능
- 문의: ironwung@gmail.com
링크
- GitHub: github.com/ironwung/litparser
- PyPI: pypi.org/project/litparser
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file litparser-1.3.9.tar.gz.
File metadata
- Download URL: litparser-1.3.9.tar.gz
- Upload date:
- Size: 103.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b522f76a2c8e4efd449a0cb926adf8fd559673862845e01e01476d13629fbcf3
|
|
| MD5 |
d016f0ae411063cf2bde2e9b54a48ad3
|
|
| BLAKE2b-256 |
2673d35c8fdc9f8f1b8a60bb35f1e4c12bcd6b327504f09e4328b9bbb2b940da
|
File details
Details for the file litparser-1.3.9-py3-none-any.whl.
File metadata
- Download URL: litparser-1.3.9-py3-none-any.whl
- Upload date:
- Size: 117.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63927934fbcc42baf6dc4d73d975392ccd28bf122a70926afdbb0386d5fcce6b
|
|
| MD5 |
8fa72c943717a773d889f77dbd2795ef
|
|
| BLAKE2b-256 |
8504e2f3af8aee38f69369abf488bd459127d7c45eaf4381372deebffe2edf74
|