파이썬에서 PDFMiner를 사용하여 PDF에서 텍스트 추출하기
파이썬으로 PDF 텍스트 추출을 완벽하게 다스리기
PDFMiner.six은 PDF 문서에서 텍스트, 메타데이터 및 레이아웃 정보를 추출하기 위한 강력한 파이썬 라이브러리입니다.
단순한 PDF 리더와 달리, PDF 구조에 대한 깊은 분석을 제공하며 복잡한 레이아웃을 효과적으로 처리합니다.

PDFMiner란 무엇이며 왜 사용해야 하나요?
PDFMiner는 PDF 문서에서 텍스트를 추출하고 분석하기 위해 설계된 순수 파이썬 라이브러리입니다. .six 버전은 파이썬 3.x를 지원하는 활발히 유지보수되는 포크이며, 원래의 PDFMiner 프로젝트는 더 이상 업데이트되지 않습니다.
주요 기능:
- 외부 종속성을 필요로 하지 않는 순수 파이썬 구현
- 상세한 레이아웃 분석 및 텍스트 위치 지정
- 글꼴 및 문자 인코딩 감지
- 암호화된 PDF 지원
- 명령줄 도구 포함
- 커스텀 처리를 위한 확장 가능한 아키텍처
PDFMiner는 텍스트 추출에 대한 정확한 제어가 필요하거나 레이아웃 정보를 유지해야 하거나 복잡한 다중 열 문서를 다루는 경우 특히 유용합니다. 다른 대안보다 속도는 느릴 수 있지만, 정확성과 상세한 분석 기능으로 인해 문서 처리 파이프라인에서 선호되는 선택입니다. 반대로 작업을 수행할 경우, 파이썬에서 PDF를 프로그래밍적으로 생성하는 방법에 관심을 가질 수 있습니다.
설치 및 설정
pip를 사용하여 PDFMiner.six를 설치합니다:
pip install pdfminer.six
가상 환경(추천):
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install pdfminer.six
파이썬 패키지 관리에 익숙하지 않다면, pip 및 가상 환경에 대한 더 많은 정보를 얻기 위해 파이썬 체크리스트를 확인하세요.
설치 확인:
pdf2txt.py --version
라이브러리는 여러 명령줄 도구를 포함합니다:
pdf2txt.py- PDF에서 텍스트 추출dumppdf.py- PDF 내부 구조 덤프latin2ascii.py- 라틴 문자를 ASCII로 변환
이 도구들은 Poppler와 같은 PDF 조작 유틸리티와 함께 사용될 수 있으며, 페이지 추출 및 형식 변환과 같은 추가 기능을 제공합니다.
기본 텍스트 추출
간단한 텍스트 추출
PDF에서 텍스트를 추출하는 가장 간단한 방법은 다음과 같습니다:
from pdfminer.high_level import extract_text
# PDF에서 모든 텍스트 추출
text = extract_text('document.pdf')
print(text)
이 고급 API는 대부분의 일반적인 사용 사례를 처리하며, 전체 문서를 단일 문자열로 반환합니다.
특정 페이지에서 텍스트 추출
특정 페이지에서 텍스트를 추출하려면:
from pdfminer.high_level import extract_text
# 페이지 2-5(0 기준)에서 텍스트 추출
text = extract_text('document.pdf', page_numbers=[1, 2, 3, 4])
print(text)
이 방법은 대규모 문서에서 특정 섹션만 필요할 경우, 성능을 크게 향상시킬 수 있습니다.
페이지별 텍스트 추출
페이지별로 처리하려면:
from pdfminer.high_level import extract_pages
from pdfminer.layout import LTTextContainer
for page_layout in extract_pages('document.pdf'):
for element in page_layout:
if isinstance(element, LTTextContainer):
print(element.get_text())
이 접근법은 페이지 구조가 다른 문서를 처리할 때 각 페이지에 대한 더 많은 제어를 제공합니다.
고급 레이아웃 분석
LAParams 이해
LAParams(레이아웃 분석 매개변수)는 PDFMiner가 문서 레이아웃을 해석하는 방법을 제어합니다. PDFMiner와 간단한 라이브러리 사이의 차이를 이해하는 것이 중요합니다 - PDFMiner는 실제로 텍스트 요소 간의 공간 관계를 분석합니다.
from pdfminer.high_level import extract_text
from pdfminer.layout import LAParams
# 사용자 정의 LAParams 생성
laparams = LAParams(
line_overlap=0.5, # 텍스트 줄의 수직 겹침 최소값
char_margin=2.0, # 같은 단어 내 문자 간격
line_margin=0.5, # 같은 단락 내 줄 간격
word_margin=0.1, # 단어 간격 임계값
boxes_flow=0.5, # 텍스트 박스 흐름 방향 임계값
detect_vertical=True, # 수직 텍스트 감지 활성화
all_texts=False # 박스 내 텍스트만 추출
)
text = extract_text('document.pdf', laparams=laparams)
매개변수 설명:
line_overlap: 줄이 동일한 줄로 간주되기 위해 수직으로 겹쳐야 하는 최소 비율 (0.0-1.0)char_margin: 같은 단어 내 문자 간격 (문자 너비의 배수로 표현)line_margin: 같은 단락 내 줄 간격word_margin: 단어를 분리하는 간격 임계값boxes_flow: 텍스트 박스 흐름 방향 임계값detect_vertical: 수직 텍스트 감지 활성화 (아시아 언어에서 흔함)all_texts: 박스 내 텍스트만 추출
레이아웃 정보 추출
상세한 위치 및 글꼴 정보를 얻는 방법:
from pdfminer.high_level import extract_pages
from pdfminer.layout import LTTextBox, LTTextLine, LTChar
for page_layout in extract_pages('document.pdf'):
for element in page_layout:
if isinstance(element, LTTextBox):
# 경계 상자 좌표 얻기
x0, y0, x1, y1 = element.bbox
print(f"({x0}, {y0}) 위치의 텍스트: {element.get_text()}")
# 줄 반복
for text_line in element:
if isinstance(text_line, LTTextLine):
# 문자 수준의 세부 정보 얻기
for char in text_line:
if isinstance(char, LTChar):
print(f"문자: {char.get_text()}, "
f"글꼴: {char.fontname}, "
f"크기: {char.height}")
이 수준의 세부 정보는 문서 분석, 양식 추출 또는 문서 구조를 프로그래밍적으로 이해할 때 매우 유용합니다.
다양한 PDF 유형 처리
암호화된 PDF
PDFMiner는 암호가 걸린 PDF를 처리할 수 있습니다:
from pdfminer.high_level import extract_text
# 암호가 걸린 PDF에서 텍스트 추출
text = extract_text('encrypted.pdf', password='your_password')
참고로, PDFMiner는 PDF 수준에서 텍스트 추출을 방지하는 보안 제한을 우회할 수는 없습니다.
다중 열 문서
다중 열 문서의 경우 LAParams를 조정하세요:
from pdfminer.high_level import extract_text
from pdfminer.layout import LAParams
# 다중 열 레이아웃 최적화
laparams = LAParams(
detect_vertical=False,
line_margin=0.3,
word_margin=0.1,
boxes_flow=0.3 # 다중 열 감지에 유리한 값
)
text = extract_text('multi_column.pdf', laparams=laparams)
boxes_flow 매개변수는 다중 열 문서에 특히 중요합니다 - 더 낮은 값은 PDFMiner가 다른 열을 구분하는 데 도움이 됩니다.
비영어 및 유니코드 텍스트
PDFMiner는 유니코드를 잘 처리하지만, 올바른 인코딩을 보장하세요:
from pdfminer.high_level import extract_text
# 유니코드 지원으로 텍스트 추출
text = extract_text('multilingual.pdf', codec='utf-8')
# UTF-8 인코딩으로 파일에 저장
with open('output.txt', 'w', encoding='utf-8') as f:
f.write(text)
스캔된 PDF 처리
PDFMiner는 스캔된 PDF(이미지)에서 텍스트를 직접 추출할 수 없습니다. 이는 OCR(광학 문자 인식)이 필요합니다. 그러나 PDFMiner를 OCR 도구와 통합할 수 있습니다.
PDF가 스캔되었는지 확인하는 방법:
from pdfminer.high_level import extract_text
from pdfminer.high_level import extract_pages
from pdfminer.layout import LTFigure, LTImage
def is_scanned_pdf(pdf_path):
"""PDF가 스캔된 것인지 확인"""
text_count = 0
image_count = 0
for page_layout in extract_pages(pdf_path):
for element in page_layout:
if isinstance(element, (LTFigure, LTImage)):
image_count += 1
elif hasattr(element, 'get_text'):
if element.get_text().strip():
text_count += 1
# 대부분 이미지이고 텍스트가 적을 경우, 스캔된 것으로 간주
return image_count > text_count * 2
if is_scanned_pdf('document.pdf'):
print("이 PDF는 스캔된 것으로 보입니다 - OCR 사용")
else:
text = extract_text('document.pdf')
print(text)
스캔된 PDF의 경우 Tesseract OCR이나 PDF에서 이미지 추출 도구를 사용하여 먼저 이미지를 추출한 후 OCR을 적용하는 것이 좋습니다.
명령줄 사용법
PDFMiner는 강력한 명령줄 도구를 포함합니다:
명령줄 도구로 텍스트 추출
# 텍스트를 표준 출력으로 추출
pdf2txt.py document.pdf
# 파일에 저장
pdf2txt.py -o output.txt document.pdf
# 특정 페이지 추출
pdf2txt.py -p 1,2,3 document.pdf
# HTML로 추출
pdf2txt.py -t html -o output.html document.pdf
고급 옵션
# 커스텀 레이아웃 매개변수
pdf2txt.py -L 0.3 -W 0.1 document.pdf
# 상세한 레이아웃 추출 (XML)
pdf2txt.py -t xml -o layout.xml document.pdf
# 암호가 걸린 PDF에 암호 설정
pdf2txt.py -P mypassword encrypted.pdf
이 명령줄 도구는 빠른 테스트, 쉘 스크립트 및 자동화된 워크플로우 통합에 매우 유용합니다.
성능 최적화
대규모 PDF 처리
대규모 문서의 경우 다음 최적화 전략을 고려하세요:
from pdfminer.high_level import extract_pages
from pdfminer.layout import LAParams
# 필요한 페이지만 처리
def extract_page_range(pdf_path, start_page, end_page):
text_content = []
for i, page_layout in enumerate(extract_pages(pdf_path)):
if i < start_page:
continue
if i >= end_page:
break
text_content.append(page_layout)
return text_content
# 속도를 위해 레이아웃 분석 비활성화
from pdfminer.high_level import extract_text
text = extract_text('large.pdf', laparams=None) # 훨씬 빠름
배치 처리
여러 PDF를 효율적으로 처리하려면:
from multiprocessing import Pool
from pdfminer.high_level import extract_text
import os
def process_pdf(pdf_path):
"""단일 PDF 파일 처리"""
try:
text = extract_text(pdf_path)
output_path = pdf_path.replace('.pdf', '.txt')
with open(output_path, 'w', encoding='utf-8') as f:
f.write(text)
return f"처리됨: {pdf_path}"
except Exception as e:
return f"{pdf_path} 처리 오류: {str(e)}"
# 병렬 처리
def batch_process_pdfs(pdf_directory, num_workers=4):
pdf_files = [os.path.join(pdf_directory, f)
for f in os.listdir(pdf_directory)
if f.endswith('.pdf')]
with Pool(num_workers) as pool:
results = pool.map(process_pdf, pdf_files)
for result in results:
print(result)
# 사용법
batch_process_pdfs('/path/to/pdfs', num_workers=4)
일반적인 문제 및 해결 방법
문제: 텍스트 순서 오류
문제: 추출된 텍스트가 어지럽거나 순서가 잘못됨.
해결 방법: LAParams를 조정하고 특히 boxes_flow를 조정하세요:
from pdfminer.layout import LAParams
laparams = LAParams(boxes_flow=0.3) # 다른 값 시도
text = extract_text('document.pdf', laparam道=laparams)
문제: 단어 간 공백 누락
문제: 단어가 공백 없이 붙어 있음.
해결 방법: word_margin을 증가시킵니다:
laparams = LAParams(word_margin=0.2) # 기본값 0.1에서 증가
text = extract_text('document.pdf', laparams=laparams)
문제: 인코딩 오류
문제: 이상한 문자나 인코딩 오류 발생.
해결 방법: 명시적으로 인코딩을 지정하세요:
text = extract_text('document.pdf', codec='utf-8')
문제: 대규모 PDF의 메모리 오류
문제: 대규모 파일에서 메모리 부족 오류 발생.
해결 방법: 페이지별로 처리하세요:
def extract_text_chunked(pdf_path, chunk_size=10):
"""메모리 사용을 줄이기 위해 텍스트를 청크로 추출"""
all_text = []
page_count = 0
for page_layout in extract_pages(pdf_path):
page_text = []
for element in page_layout:
if hasattr(element, 'get_text'):
page_text.append(element.get_text())
all_text.append(''.join(page_text))
page_count += 1
# 청크로 처리
if page_count % chunk_size == 0:
yield ''.join(all_text)
all_text = []
# 남은 텍스트 처리
if all_text:
yield ''.join(all_text)
PDFMiner 대안과 비교
PDFMiner를 사용할 때와 다른 라이브러리를 사용할 때의 차이를 이해하는 것이 중요합니다:
PDFMiner vs PyPDF2
PyPDF2는 더 간단하고 빠르지만 정확도가 낮습니다:
- PyPDF2 사용 시: 간단한 PDF, 빠른 추출, PDF 병합/분할
- PDFMiner 사용 시: 복잡한 레이아웃, 정확한 텍스트 위치, 상세한 분석
PDFMiner vs pdfplumber
pdfplumber는 PDFMiner에 기반하여 더 높은 수준의 API를 제공합니다:
- pdfplumber 사용 시: 테이블 추출, 간단한 API, 빠른 프로토타이핑
- PDFMiner 사용 시: 최대 제어, 커스텀 처리, 프로덕션 시스템
PDFMiner vs PyMuPDF (fitz)
PyMuPDF는 C 종속성이 있지만 훨씬 빠릅니다:
- PyMuPDF 사용 시: 성능 중심의 애플리케이션, 대규모 처리
- PDFMiner 사용 시: 순수 파이썬 요구, 상세한 레이아웃 분석
실용적인 예제: 문서 추출 및 분석
다음은 텍스트를 추출하고 문서 통계를 제공하는 완전한 예제입니다:
from pdfminer.high_level import extract_pages, extract_text
from pdfminer.layout import LTTextBox, LTChar
from collections import Counter
import re
def analyze_pdf(pdf_path):
"""텍스트 추출 및 문서 분석"""
# 전체 텍스트 추출
full_text = extract_text(pdf_path)
# 통계
stats = {
'total_chars': len(full_text),
'total_words': len(full_text.split()),
'total_lines': full_text.count('\n'),
'fonts': Counter(),
'font_sizes': Counter(),
'pages': 0
}
# 상세 분석
for page_layout in extract_pages(pdf_path):
stats['pages'] += 1
for element in page_layout:
if isinstance(element, LTTextBox):
for line in element:
for char in line:
if isinstance(char, LTChar):
stats['fonts'][char.fontname] += 1
stats['font_sizes'][round(char.height, 1)] += 1
return {
'text': full_text,
'stats': stats,
'most_common_font': stats['fonts'].most_common(1)[0] if stats['fonts'] else None,
'most_common_size': stats['font_sizes'].most_common(1)[0] if stats['font_sizes'] else None
}
# 사용법
result = analyze_pdf('document.pdf')
print(f"페이지 수: {result['stats']['pages']}")
print(f"단어 수: {result['stats']['total_words']}")
print(f"주요 글꼴: {result['most_common_font']}")
print(f"주요 크기: {result['most_common_size']}")
문서 처리 파이프라인과의 통합
PDFMiner는 더 큰 문서 처리 워크플로우에서 잘 작동합니다. 예를 들어, RAG(검색 기반 생성) 시스템이나 문서 관리 솔루션을 구축할 때, 다른 파이썬 도구와 결합하여 완전한 파이프라인을 만들 수 있습니다.
PDF에서 텍스트를 추출한 후, 다른 형식으로 변환해야 할 경우가 많습니다. 파이썬 라이브러리를 사용하여 HTML 콘텐츠를 마크다운으로 변환하거나, 심지어 LLM 기반 변환을 사용하여 Ollama 활용하여 지능적인 문서 변환을 수행할 수 있습니다. 이러한 기술은 PDF 추출이 HTML과 같은 구조화된 텍스트를 생성할 때 청소 및 재포맷팅이 필요한 경우 특히 유용합니다.
포괄적인 문서 변환 파이프라인을 구축할 때는 워드 문서를 마크다운으로 변환을 고려해야 하며, 여러 문서 형식을 공통 출력 형식으로 처리하는 통합 워크플로우를 생성할 수 있습니다.
최선의 실천 방법
- 복잡한 문서에 항상 LAParams 사용 - 기본 설정은 간단한 문서에 적합하지만, 복잡한 레이아웃의 경우 LAParams를 조정하여 결과를 크게 향상시킬 수 있습니다.
- 샘플 페이지로 먼저 테스트 - 대규모 배치를 처리하기 전에 대표적인 샘플로 추출 설정을 테스트하세요.
- 예외를 부드럽게 처리 - PDF 파일이 손상되었거나 잘못되었을 수 있으므로, 항상 추출 코드를 try-except 블록으로 감싸세요.
- 추출된 텍스트를 캐시 - 반복 처리 시, 추출된 텍스트를 캐시하여 재처리를 피하세요.
- 추출된 텍스트를 검증 - 추출 품질을 확인하기 위해 최소 텍스트 길이, 예상 키워드 등 검사를 구현하세요.
- 특정 사용 사례에 대안 고려 - PDFMiner는 강력하지만, 테이블을 위한 전용 도구(예: tabula-py)가 더 적합한 경우도 있습니다.
- PDFMiner 업데이트 유지 -
.six포크는 활발히 유지보수되고 있으므로, 버그 수정 및 개선을 위해 항상 업데이트하세요. - 코드를 문서화 - PDF 추출 스크립트를 공유할 때, 마크다운 코드 블록과 함께 구문 강조를 사용하여 가독성을 높이세요.
결론
PDFMiner.six는 파이썬 개발자가 PDF 문서를 다루는 데 필수적인 도구입니다. 순수 파이썬 구현, 상세한 레이아웃 분석, 확장 가능한 아키텍처로 인해 생산성 문서 처리 시스템에 이상적입니다. 간단한 라이브러리보다 학습 곡선이 더 가파르지만, 복잡한 PDF 추출 작업에 필요한 정확성과 제어는 비타협적입니다.
문서 관리 시스템을 구축하거나 과학 논문을 분석하거나 머신러닝 파이프라인에 데이터를 추출하는 경우, PDFMiner는 파이썬에서 신뢰할 수 있는 PDF 텍스트 추출 기초를 제공합니다.
관련 자료
이 사이트의 관련 기사
- Ubuntu에서 PDF 조작 도구 - Poppler - pdftotext, pdfimages 및 기타 poppler 유틸리티를 포함한 명령줄 PDF 도구에 대한 포괄적인 가이드로, PDFMiner과 문서 처리 워크플로우에서 함께 사용됩니다.
- PDF에서 이미지 추출 - 체크리스트 - PDF에서 내장 이미지를 추출하는 방법을 배우고, PDFMiner의 텍스트 추출 기능과 보완합니다.
- 파이썬에서 PDF 생성 - 라이브러리 및 예제 - PDF 텍스트 추출의 역으로 PDF를 생성하는 데 사용할 수 있는 파이썬 라이브러리인 ReportLab, PyPDF2, FPDF를 탐구합니다.
- 파이썬 체크리스트 - 파일 처리, 문자열 연산 및 깨끗한 PDF 처리 스크립트 작성에 대한 최고의 실천 방법을 포함한 필수 파이썬 구문 참조.
- HTML을 마크다운으로 변환하는 방법: 포괄적인 가이드 - 문서 변환 파이프라인을 구축할 때, PDF 또는 웹에서 추출된 HTML을 마크다운 형식으로 변환하는 방법을 배우세요.
- LLM 및 Ollama를 사용하여 HTML 콘텐츠를 마크다운으로 변환 - 추출된 PDF 텍스트를 정리하기 위해 로컬 LLM을 사용하는 고급 기술.
- 마크다운 코드 블록 사용법 - PDF 추출 코드를 문서화하기 위해 마크다운 구문과 강조를 정확히 사용하는 방법을 마스터하세요.
- 워드 문서를 마크다운으로 변환: 완전한 가이드 - 여러 플랫폼에서 문서 처리 파이프라인을 위한 워드, PDF 및 기타 형식의 완전한 문서 변환 가이드.