콘텐츠로 이동

36. PDF 텍스트 추출 - 사진 찍은 책에서 글자 따오기

한 줄 요약

PDF는 텍스트 파일이 아니라 "그림 그리는 명령어 모음"이다. 그래서 PDF에서 텍스트 추출은 항상 추정. 100% 정확도 불가능.

PDF의 정체

PDF 안을 들여다보면 이런 명령어가 들어 있어:

y=297 위치에 폰트 A, 12pt로 '꼼꼼히' 그려라
y=297 위치에 폰트 A, 12pt로 '고려' 그려라
y=320 위치에 폰트 A, 12pt로 '하여' 그려라

이게 다야. "단어 사이가 띄어쓰기였는지 줄바꿈이었는지" 정보가 없어.

비유하면 책을 사진 찍은 것. 사진에 글자는 다 보이지만, 줄 끝에서 "고려/하여"가 한 단어("고려하여")였는지 두 단어("고려 하여")였는지는 글자 모양만 보고 추측해야 해.

왜 자동 변환이 어려운가

같은 줄 안은 OK

한 줄: "이 책은 병원을 개원하는 원장님들이"
→ 글자 사이 간격이 큰 곳 = 띄어쓰기 ✓ 정확

줄바꿈에선 정보 사라짐

줄 1 끝: "고려"
줄 2 시작: "하여"

→ 진짜 "고려하여" 한 단어? 아니면 "고려" + "하여" 두 단어?
→ 사진만 보고는 알 수 없음

한국어는 더 어려워. 영어는 단어 사이 공백이 명확하지만, 한국어는 음절 단위로 줄바꿈됨.

도구별 PDF→텍스트 변환 비교

병원 인테리어 책(252p)으로 검증한 결과:

도구 "실무지침서" "원장님들에게" 평가
Microsoft Word "실무 지침서" ✗ "원장님 들에게" ✗ 줄바꿈을 무조건 공백으로
Calibre ebook-convert "실무지침서" ✓ "원장님 들에게" ✗ 영어 기준, 한국어 일부만
PyMuPDF + 휴리스틱 "실무 지침서" ✗ "원장님들에게" ✓ 한국어 어미/조사로 추정
PyMuPDF + PDF 사전 "실무지침서" ✓ "원장님들에게" ✓ 책 자체 학습

핵심 발견: 어떤 도구를 쓰든 PDF 자체의 한계 때문에 100% 정확하지 않음. PDF 사전 매칭(책 안에서 같은 단어가 다른 페이지에 한 단어로 등장하는지 확인)이 가장 정확.

답이 책 안에 있다 - PDF 페어 사전 매칭

이번에 발견한 신기한 아이디어:

"실무지침서"가 PDF의 다른 페이지에서 한 단어로 등장했나?
  → 한 단어 ✓ 합쳐!

"수 있는"이 PDF의 다른 페이지에서 띄어진 페어로 등장했나?
  → 띄어쓰기 ✓ 띄워!

비유: 시험 문제 답이 같은 시험지 안 어디엔가 있는 셈. 책 전체를 스캔해서 "이 책에선 이 단어를 이렇게 쓴다"는 사전을 만들면, 줄바꿈에서 헷갈리는 부분을 책 자체 데이터로 판단 가능.

병원 인테리어 책 결과: - 단어 사전: 6,676개 - 페어 사전: 12,203개 - 띄어쓰기 정확도: 98% (PDF 시각 기준) / 거의 100% (작가 원고 의도 기준)

100% 정확하게 하려면 - 원본 받기

PDF만으로는 추정의 한계. 진짜 100% 원하면:

  1. InDesign 원본 (.indd, .idml) ⭐ 최선
  2. 디자이너가 만든 원본 파일. 텍스트 흐름이 그대로 저장됨
  3. 인쇄 줄바꿈은 시각적 결과일 뿐, 원본 텍스트는 흐름 그대로

  4. 작가 워드 원고 (.docx, .hwp)

  5. 디자인 전 작가가 쓴 원고. 줄바꿈 없이 단락 단위
  6. 띄어쓰기 정확

  7. 출판사 납품용 텍스트

  8. 서점 등록용 책 소개 파일 같은 거

받으면 5분 안에 0% 차이 EPUB 가능.

PyMuPDF 추출 모드 4가지 (실용 가이드)

import fitz
doc = fitz.open("책.pdf")
page = doc[0]

# 1. text - 그냥 텍스트
page.get_text()
# → "이 책은 병원을 개원하는..."
# 가장 단순, 띄어쓰기 일부 손실

# 2. dict - 줄 단위 + 폰트 크기 + 좌표
page.get_text("dict")
# → {"blocks": [{"lines": [{"spans": [{"text": "...", "size": 10.6, "bbox": [...]}]}]}]}
# 챕터 헤딩 식별 등 (size로 본문/제목 구분)

# 3. words - 단어 단위 + 좌표
page.get_text("words")
# → [(x0, y0, x1, y1, "단어", block_no, line_no, word_no), ...]
# 띄어쓰기 100% 보존 (같은 줄 내), 단어 사전 만들 때

# 4. rawdict - 글자 단위 + 좌표
page.get_text("rawdict")
# → 각 글자의 정확한 위치. PDF 디버깅용
# "정말 PDF에 공백이 있나?" 확인할 때
모드 단위 좌표 폰트 추천 용도
text 페이지 빠른 검색
dict 챕터/헤딩 식별
words 단어 띄어쓰기 보존, 사전 구축
rawdict 글자 디버깅

다음 PDF 작업 시 체크리스트

비슷한 책 작업할 때 이 순서로:

  1. 원본 파일 먼저 요청 - 작가/디자이너에게 .indd/.idml/.docx 있는지 물어보기
  2. 없으면 PDF로 진행:
  3. PyMuPDF get_text("words") 모드 사용 (텍스트 모드 X)
  4. PDF 페어 사전 만들기 (책 안에서 답 찾기)
  5. 표 페이지는 텍스트 추출 포기, 페이지 PNG로 대체
  6. 양면 스프레드 사진은 좌우 페이지 이미지 합쳐서 1장으로
  7. 글자 누락 0 확인 (verify_pages.py)
  8. 띄어쓰기 차이 1~2% 까지 자동화. 그 이상은 작가 검수
  9. EPUB 빌드 후 verify_report.html로 페이지별 시각 검수

활용 가능한 다른 자동화

PDF 사전 매칭 아이디어는 다른 곳에도 응용 가능:

  • 작가별 글쓰기 패턴 사전 - 이 작가는 "수있다"인지 "수 있다"인지
  • 회사명/병원명 보호 사전 - 고유명사 띄어쓰기 안 깨지게
  • 키워드 일관성 검증 - 책 전체에서 같은 용어 표기 통일됐는지
  • 번역서 용어 통일 - 한 단어로 합의된 번역어가 책 전체에 일관되는지

핵심 원리: 답이 자료 안에 있다. 자료 전체를 스캔해서 패턴을 찾자.

작업 사례

병원 인테리어 책 (D:\ebook-project\작업\260423 병원인테리어-책\전자책 빌드\): - 252페이지 인쇄용 PDF(100MB) → 22.5MB EPUB - 글자 누락 0자, 띄어쓰기 1.97% 차이 (인쇄 줄바꿈 흔적) - 작업 시간 약 4시간 (스크립트 작성 포함) - 다음 비슷한 책: 1~2시간 안에 가능 (스크립트 재사용)

한계 인정

자동화 한계 = 1~2% 띄어쓰기 차이. - 이건 PDF 자체 한계지 알고리즘 문제 아님 - 작가가 EPUB 검수 시 어색한 부분 수동 수정하는 게 합리적 - 또는 InDesign 원본 받기 (5분 만에 0%)

완벽주의 함정 피하기: 1.97% 차이 잡으려고 5시간 더 쓰는 것보다 작가가 30분 검수하는 게 합리적. 또는 원본 파일 요청.

같이 보면 좋은 문서

  • study/28-epub-구조와-빌드.md - EPUB 파일 구조
  • study/14-hwp-com-automation.md - HWP 자동화 (PDF의 한국 사촌)
  • memory/indesign_pdf_to_epub_workflow.md - 실전 파이프라인 v3 상세