본문 바로가기
카테고리 없음

파이썬으로 PDF에서 텍스트 자동 추출하기 (계약서·보고서 데이터화)

by First Adventure 2026. 4. 18.
반응형

문서 100개, 파이썬은 3초면 끝납니다.

  거래처에서 받은 계약서 PDF, 매달 쌓이는 세금계산서, 수십 페이지짜리 입찰 제안서. 내용을 엑셀로 옮기거나 특정 항목만 뽑아야 할 때, 결국 눈으로 읽고 손으로 타이핑하고 있진 않으신가요? 파일이 한두 개라면 모를까, 수십 개가 넘어가는 순간 이 작업은 반나절을 통째로 날립니다.

  이 글에서는 파이썬으로 PDF 파일에서 텍스트를 자동으로 추출하는 방법을 다룹니다. 텍스트가 선택되는 일반 PDF부터, 스캔해서 이미지로만 된 PDF까지 두 가지 경우를 모두 다룹니다.

 

PDF의 두 가지 종류부터 확인하세요

  시작 전에 반드시 확인해야 할 것이 있습니다. PDF에는 크게 두 가지 종류가 있고, 종류에 따라 사용하는 도구가 완전히 달라집니다.

  • 텍스트 PDF: 파일을 열었을 때 마우스로 텍스트를 드래그해서 복사할 수 있는 PDF입니다. 워드·한글·엑셀 등에서 내보낸 파일이 여기에 해당합니다. pdfplumber 또는 PyMuPDF로 추출합니다.
  • 이미지 PDF (스캔본): 종이 문서를 스캐너로 찍어서 만든 PDF입니다. 텍스트가 이미지로 저장되어 있어 드래그해도 선택이 안 됩니다. OCR(광학 문자 인식) 기술이 필요하며 pytesseract를 사용합니다.

  확인 방법은 간단합니다. PDF를 열어서 텍스트를 마우스로 드래그해보세요. 선택이 된다면 텍스트 PDF, 선택이 안 된다면 이미지 PDF입니다.

 

사전 준비: 라이브러리 설치

텍스트 PDF용

pip install pdfplumber pymupdf
  • pdfplumber: 텍스트 추출뿐 아니라 PDF 안의 표(테이블)도 구조를 유지한 채 추출할 수 있어 계약서·보고서 처리에 특히 유용합니다.
  • PyMuPDF (fitz): 속도가 매우 빠르고 안정적입니다. 대용량 PDF나 파일 수가 많을 때 적합합니다.

 

이미지 PDF (스캔본)용

pip install pytesseract pdf2image Pillow

  pytesseract는 파이썬 라이브러리 설치 외에 Tesseract OCR 엔진을 별도로 설치해야 합니다. 아래 링크에서 Windows용 설치 파일을 받아 실행합니다.

 

Case 1. 텍스트 PDF에서 본문 추출하기

pdfplumber 사용 (기본 텍스트 추출)

  계약서·보고서처럼 텍스트 위주의 PDF에서 전체 내용을 추출하는 가장 기본적인 방법입니다.

# extract_text.py
import pdfplumber

pdf_path = "contract.pdf"  # 추출할 PDF 파일 경로

with pdfplumber.open(pdf_path) as pdf:
    for i, page in enumerate(pdf.pages):
        text = page.extract_text()
        if text:
            print(f"--- {i+1}페이지 ---")
            print(text)

 

PyMuPDF 사용 (빠른 대량 처리)

  파일 수가 많거나 페이지가 많은 PDF를 빠르게 처리할 때 적합합니다. pdfplumber보다 처리 속도가 눈에 띄게 빠릅니다.

# extract_text_fast.py
import fitz  # PyMuPDF

pdf_path = "contract.pdf"

doc = fitz.open(pdf_path)
for i, page in enumerate(doc):
    text = page.get_text()
    if text.strip():
        print(f"--- {i+1}페이지 ---")
        print(text)
doc.close()

 

Case 2. PDF 안의 표(테이블) 추출하기

  계약서 단가표, 보고서 통계표처럼 PDF 안에 표가 있는 경우, pdfplumber는 표 구조를 그대로 살려서 추출할 수 있습니다. 추출한 데이터는 pandas DataFrame으로 바로 변환해 엑셀로 저장할 수 있습니다.

# extract_table.py
import pdfplumber
import pandas as pd

pdf_path = "report.pdf"

with pdfplumber.open(pdf_path) as pdf:
    all_tables = []

    for i, page in enumerate(pdf.pages):
        tables = page.extract_tables()  # 페이지 안의 모든 표 추출

        for j, table in enumerate(tables):
            # 첫 번째 행을 헤더로 사용해 DataFrame 생성
            df = pd.DataFrame(table[1:], columns=table[0])
            df["출처_페이지"] = i + 1
            df["출처_표번호"] = j + 1
            all_tables.append(df)
            print(f"{i+1}페이지 표 {j+1}: {len(df)}행 추출")

if all_tables:
    result = pd.concat(all_tables, ignore_index=True)
    result.to_excel("tables_extracted.xlsx", index=False)
    print(f"\n완료! 총 {len(result)}행이 저장되었습니다.")
else:
    print("추출된 표가 없습니다.")

 

Case 3. 스캔본 PDF에서 OCR로 텍스트 추출하기

  스캐너로 찍은 PDF는 텍스트가 이미지로 저장되어 있어 일반 추출 방법이 통하지 않습니다. PDF를 이미지로 변환한 뒤 OCR 엔진으로 텍스트를 인식하는 방식을 사용합니다.

# extract_ocr.py
import pytesseract
from pdf2image import convert_from_path
from PIL import Image

# Tesseract 설치 경로 지정 (Windows 기준, 설치 경로 확인 후 수정)
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

pdf_path = "scanned_contract.pdf"

# PDF를 페이지별 이미지로 변환 (dpi가 높을수록 인식률 향상, 처리 속도는 느려짐)
pages = convert_from_path(pdf_path, dpi=300)

full_text = ""
for i, page_image in enumerate(pages):
    # 한국어+영어 동시 인식: lang="kor+eng"
    text = pytesseract.image_to_string(page_image, lang="kor+eng")
    print(f"--- {i+1}페이지 ---")
    print(text)
    full_text += f"\n--- {i+1}페이지 ---\n" + text

# 전체 텍스트를 txt 파일로 저장
with open("ocr_result.txt", "w", encoding="utf-8") as f:
    f.write(full_text)

print("\n완료! ocr_result.txt 에 저장되었습니다.")

 

Case 4. 폴더 안의 PDF 파일 여러 개를 한번에 처리하기

  계약서나 보고서가 여러 개일 때, 폴더 안의 모든 PDF를 순서대로 읽어 결과를 하나의 엑셀 파일로 저장합니다.

# batch_extract.py
import pdfplumber
import pandas as pd
import glob
import os

folder_path = "pdf_files"  # PDF 파일이 있는 폴더
file_list = sorted(glob.glob(os.path.join(folder_path, "*.pdf")))
print(f"발견된 PDF 파일 수: {len(file_list)}개\n")

results = []

for file in file_list:
    filename = os.path.basename(file)
    try:
        with pdfplumber.open(file) as pdf:
            full_text = ""
            for page in pdf.pages:
                text = page.extract_text()
                if text:
                    full_text += text + "\n"

        results.append({
            "파일명": filename,
            "총페이지": len(pdf.pages),
            "추출텍스트": full_text.strip()
        })
        print(f"완료: {filename}")

    except Exception as e:
        print(f"건너뜀: {filename} → {e}")
        results.append({
            "파일명": filename,
            "총페이지": 0,
            "추출텍스트": f"[오류] {e}"
        })

df = pd.DataFrame(results)
df.to_excel("pdf_extracted_all.xlsx", index=False)
print(f"\n완료! 총 {len(results)}개 파일 처리 → pdf_extracted_all.xlsx 저장")

 

자주 발생하는 문제와 해결법

문제 1. 추출한 텍스트에 줄바꿈이 이상하게 들어올 때

  PDF의 레이아웃 구조상 줄바꿈이 의도치 않은 위치에 들어오는 경우가 많습니다. 후처리로 정리합니다.

# 불필요한 줄바꿈 제거 후 문단 단위로 정리
text = page.extract_text()

# 빈 줄은 문단 구분으로 유지하되, 단순 줄바꿈은 공백으로 변환
lines = text.split("\n")
cleaned = " ".join(line.strip() for line in lines if line.strip())
print(cleaned)

 

문제 2. 한글이 깨지거나 ? 로 출력될 때

  텍스트를 파일로 저장할 때 인코딩을 반드시 utf-8로 지정해야 합니다. OCR의 경우 Tesseract 설치 시 한국어 팩이 누락된 경우입니다.

# 파일 저장 시 반드시 encoding="utf-8" 지정
with open("result.txt", "w", encoding="utf-8") as f:
    f.write(text)

# OCR 한국어 팩 재설치 (Tesseract 설치 시 Korean 체크 확인)
# 설치 후 아래 명령어로 인식 언어 목록 확인
# tesseract --list-langs

 

문제 3. 비밀번호가 걸린 PDF일 때

  pdfplumber는 비밀번호가 걸린 PDF를 열 때 password 인자를 지원합니다.

with pdfplumber.open("locked.pdf", password="1234") as pdf:
    text = pdf.pages[0].extract_text()
    print(text)

 

문제 4. pdfplumber로 표가 추출되지 않을 때

  PDF에 따라 표의 경계선이 명확하지 않아 자동 감지가 안 되는 경우가 있습니다. 이럴 때는 표 감지 설정을 조정하거나, 텍스트를 추출한 뒤 직접 파싱하는 방식으로 전환합니다.

# 표 감지 설정을 느슨하게 조정
table_settings = {
    "vertical_strategy": "text",    # 선 대신 텍스트 위치 기준으로 열 감지
    "horizontal_strategy": "text",  # 선 대신 텍스트 위치 기준으로 행 감지
}

with pdfplumber.open("report.pdf") as pdf:
    for page in pdf.pages:
        tables = page.extract_tables(table_settings)
        for table in tables:
            print(table)

 

상황별 도구 선택 정리

  • 텍스트 추출, 파일 수가 적을 때: pdfplumber — 사용법이 직관적이고 표 추출까지 지원합니다.
  • 텍스트 추출, 파일 수가 많거나 속도가 중요할 때: PyMuPDF(fitz) — 처리 속도가 가장 빠릅니다.
  • PDF 안의 표를 엑셀로 변환할 때: pdfplumber + pandas 조합이 가장 깔끔합니다.
  • 스캔본(이미지 PDF)일 때: pdf2image + pytesseract — OCR이 필요하며 인식률은 문서 품질에 따라 달라집니다.

 

마치며..

  오늘은 파이썬으로 PDF에서 텍스트와 표를 자동 추출하는 방법을 상황별로 살펴보았습니다. 기술의 목적은 결국 인간의 시간을 더 가치 있는 곳에 쓰게 하는 것입니다. 계약서를 손으로 옮기는 작업은 파이썬에게 맡기고, 여러분은 그 데이터로 더 중요한 판단에 집중하시길 바랍니다.

  추출한 데이터를 엑셀 파일 여러 개와 합쳐야 한다면, 이전 글 파이썬으로 엑셀 파일 100개 한번에 합치기를 함께 참고해 보세요. 두 가지를 조합하면 PDF 수집부터 데이터 통합까지 하나의 파이프라인으로 만들 수 있습니다.

 

관련 내용

 


본 포스팅의 코드는 자유롭게 수정 및 배포가 가능하나, 상업적 이용 시에는 출처를 반드시 밝혀주시기 바랍니다.

 

반응형