Python에서 PDF 텍스트 추출 방법 (2026)

발행: (2026년 3월 16일 PM 06:21 GMT+9)
13 분 소요
원문: Dev.to

Source: Dev.to

Source:

PDF에서 텍스트 추출하기

PDF에서 텍스트를 추출하는 일은 데이터 엔지니어링, AI 파이프라인, 자동화 워크플로우에서 여전히 가장 흔한 작업 중 하나입니다. 검색 시스템을 구축하든, 검색‑증강 생성(RAG) 파이프라인을 만들든, 혹은 단순히 보고서를 처리하든, 첫 번째 단계는 PDF를 깔끔하고 활용 가능한 텍스트로 변환하는 것입니다.

언뜻 보기엔 간단해 보이지만, PDF는 현대 포맷처럼 기계가 읽기 쉽게 설계되지 않았습니다. PDF는 본질적으로 페이지가 어떻게 보여야 하는지를 설명하는 명령어 집합이며, 문단, 제목, 표와 같은 구조화된 표현이 아닙니다. 따라서 텍스트가 조각으로 저장되거나 임의의 위치에 배치되거나 이미지로 삽입될 수 있습니다.

이 때문에 기본적인 추출은 종종 문장이 끊기거나, 읽기 순서가 잘못되거나, 내용이 누락되는 결과를 낳습니다. 최신 도구들은 단순히 원시 텍스트 스트림을 읽는 것이 아니라 구조를 재구성하려고 시도하기 때문에, 추출 방법 선택이 중요합니다.

PDF 텍스트 추출 작동 방식

대부분의 PDF 추출 파이프라인은 다음과 같은 고수준 프로세스를 따릅니다:

  1. 문서를 페이지 단위로 파싱한다.
  2. 텍스트 블록을 감지하고 읽을 수 있는 순서로 조합한다.
  3. 문서에 스캔된 페이지가 포함되어 있으면 OCR을 적용한다.
  4. 출력을 정규화하여 인덱싱, 검색 또는 다운스트림 시스템에 전달할 수 있게 만든다.

이 워크플로우는 직관적으로 보이지만, 각 단계마다 예상보다 많은 복잡성이 존재합니다. 읽기 순서 감지는 다중 컬럼 레이아웃이나 기술 문서에서 어려워집니다. 표는 시각적 구조가 텍스트와 항상 깔끔하게 매핑되지 않기 때문에 또 다른 난관을 제공합니다.

이러한 이유로 많은 팀이 단순 PDF 라이브러리를 넘어 보다 완전한 문서‑처리 프레임워크로 이동하게 됩니다.

Python에서 PDF 텍스트 추출하기

Python에서는 사용되는 라이브러리에 관계없이 텍스트 추출 기본 워크플로우가 동일합니다:

  1. 문서를 로드한다.
  2. 파싱한다.
  3. 텍스트로 변환하여 출력하거나 저장하거나 추가로 처리한다.

다양한 라이브러리가 서로 다른 API를 제공하지만, 전반적인 패턴은 일관됩니다. 실제 차이는 레이아웃 처리 능력, 성능, OCR 지원 여부에서 나타납니다.

Source:

Kreuzberg를 사용한 PDF 추출

현대 문서 파이프라인은 단순히 텍스트 스트림을 읽는 것 이상을 요구합니다. 일관된 메타데이터, 다양한 포맷에 대한 신뢰성 있는 처리, 그리고 대량 파일을 처리할 때의 좋은 성능이 필요합니다.

Kreuzberg는 이러한 작업 부하를 위해 설계되었습니다. Rust 기반 추출 엔진에 Python 바인딩을 제공하며(2026년 3월 현재 11개의 다른 프로그래밍 언어도 지원), 효율적인 문서 처리를 가능하게 하고 Python 파이프라인에 원활하게 통합됩니다.

설치

pip install kreuzberg

동기식 추출

from kreuzberg import extract_file_sync

result = extract_file_sync("document.pdf")
print(result.content)                         # 추출된 텍스트
print(f"Pages: {result.metadata['page_count']}")  # 페이지 수

비동기식 추출

import asyncio
from kreuzberg import extract_file

async def main():
    result = await extract_file("document.pdf")
    print(result.content)                         # 추출된 텍스트
    print(f"Tables found: {len(result.tables)}")  # 테이블 수

asyncio.run(main())

두 함수 모두 ExtractionResult 객체를 반환합니다. 이 객체는 다음을 포함합니다:

  • result.content – 추출된 텍스트.
  • result.tables – 감지된 테이블 목록.
  • result.metadata – 문서 속성(예: 페이지 수, 포맷).

배치 추출 (동기)

from pathlib import Path
from kreuzberg import batch_extract_files_sync

paths = list(Path("documents").glob("*.pdf"))
results = batch_extract_files_sync(paths)

for path, result in zip(paths, results):
    print(f"{path.name}: {len(result.content)} characters")

배치 헬퍼는 동시성을 자동으로 처리하므로 많은 PDF를 한 번에 쉽게 처리할 수 있습니다.

스캔된 PDF용 OCR

ExtractionConfigOcrConfig를 전달하여 OCR을 활성화합니다.

Tesseract (영어)

from kreuzberg import extract_file_sync, ExtractionConfig, OcrConfig

config = ExtractionConfig(
    ocr=OcrConfig(backend="tesseract", language="eng")
)

result = extract_file_sync("scanned.pdf", config=config)
print(result.content)

PaddleOCR (중국어)

from kreuzberg import extract_file_sync, ExtractionConfig, OcrConfig

config = ExtractionConfig(
    ocr=OcrConfig(backend="paddleocr", language="zh")
)

result = extract_file_sync("scanned.pdf", config=config)
print(f"Extracted content (preview): {result.content[:100]}")
print(f"Total characters: {len(result.content)}")

일반적인 런타임 문제

libonnxruntime.so 로드 오류가 발생하면 먼저 onnxruntime을 업그레이드/설치합니다:

python -m pip install --upgrade onnxruntime

Linux에서 오류가 지속될 경우 onnxruntime/capi 디렉터리를 LD_LIBRARY_PATH에 추가합니다 (<venv_path>를 실제 가상 환경 경로로 교체):

export LD_LIBRARY_PATH="/<venv_path>/lib/pythonX.Y/site-packages/onnxruntime/capi:$LD_LIBRARY_PATH"

Kreuzberg는 Tesseract, EasyOCR, PaddleOCR를 백엔드로 지원하므로, 언어별로 백엔드 품질이 달라지는 다국어 문서 처리에 유용합니다.

표와 구조화된 콘텐츠 추출

표는 단순 추출 방식이 어려움을 겪는 또 다른 영역입니다. 텍스트가 올바르게 캡처되더라도 행과 열 사이의 관계가 손실될 수 있습니다.

보다 고급의 추출 파이프라인은 표 영역을 감지하고 구조를 보존하려 시도합니다. 이렇게 하면 데이터가 계속 활용 가능하게 됩니다. 이는 표에 가장 중요한 정보가 담겨 있는 경우가 많은 재무 보고서, 연구 논문, 운영 문서 등에서 특히 중요합니다.

성능 및 확장성 고려사항

Performance becomes increasingly important as soon as you begin processing more than a handful of files.
파일을 몇 개 이상 처리하기 시작하면 성능이 점점 더 중요해집니다.

Batch ingestion, RAG pipelines, and search‑indexing workflows may involve thousands or millions of documents, and inefficiencies at the parsing stage quickly become expensive.
배치 수집, RAG 파이프라인, 검색 인덱싱 워크플로는 수천 개에서 수백만 개의 문서를 포함할 수 있으며, 파싱 단계에서의 비효율은 빠르게 비용으로 이어집니다.

Several factors influence performance, including:
성능에 영향을 미치는 여러 요인이 있습니다:

  • Implementation – how the parsing engine is written (compiled vs. interpreted).
    Implementation – 파싱 엔진이 어떻게 작성되었는지(컴파일 vs. 인터프리터).

  • Memory management – efficient use of RAM and streaming of large files.
    Memory management – RAM을 효율적으로 사용하고 대용량 파일을 스트리밍하는 방식.

  • Concurrency support – ability to run multiple parses in parallel.
    Concurrency support – 여러 파싱을 병렬로 실행할 수 있는 능력.

Tools that rely heavily on interpreted execution or external subprocesses often encounter bottlenecks at scale, while native parsing engines tend to perform better under sustained workloads.
인터프리터 실행이나 외부 서브프로세스에 크게 의존하는 도구는 대규모 환경에서 병목 현상이 자주 발생하지만, 네이티브 파싱 엔진은 지속적인 워크로드에서 더 나은 성능을 보이는 경향이 있습니다.

This is one reason many modern document‑processing tools use compiled cores with language bindings on top.
이것이 많은 최신 문서 처리 도구가 상단에 언어 바인딩을 갖춘 컴파일된 코어를 사용하는 이유 중 하나입니다.

현대 파이프라인에서 PDF 추출의 위치

대부분의 실제 시스템에서 텍스트 추출은 첫 번째 단계에 불과합니다. 텍스트가 확보되면 일반적으로 다음과 같이 진행됩니다:

  1. 청크로 분할한다.
  2. 임베딩으로 변환한다.
  3. 검색을 위해 벡터 데이터베이스에 저장한다.

이 아키텍처는 대량의 문서 컬렉션을 효율적으로 조회할 수 있게 해주기 때문에 문서 검색 및 Retrieval‑Augmented Generation(RAG) 시스템의 표준이 되었습니다. 신뢰할 수 있는 추출은 나머지 모든 것을 가능하게 하는 기반입니다.

일반적인 함정

PDF 추출을 처음 접하는 개발자들은 모든 PDF가 동일하게 동작한다고 가정하는 경우가 많습니다. 실제로 문서는 구조와 품질이 크게 다양하며, 한 데이터셋에 잘 작동하던 파이프라인이 다른 데이터셋에서는 실패할 수 있습니다.

함정을 피하기 위한 팁

  • 다양한 문서로 테스트하기 – 스캔된 파일, 다중 컬럼 레이아웃, 대형 보고서를 포함합니다. 현실적인 조건에서 문제는 보통 빠르게 나타납니다.
  • 메타데이터를 무시하지 않기 – 페이지 번호, 제목, 문서 계층 구조는 나중에 특히 출처를 인용해야 하는 검색 시스템을 구축할 때 중요해지는 경우가 많습니다.

Final Thoughts

Python에서 PDF 텍스트를 추출하는 것이 몇 년 전보다 쉬워졌지만, 문서 구조와 레이아웃의 근본적인 문제는 여전히 남아 있습니다. 이러한 복잡성을 잘 처리하는 도구를 선택하면 검색, RAG, 분석 등 하위 시스템의 품질을 크게 향상시킬 수 있습니다. 인제스트 레이어가 신뢰할 수 있게 되면 파이프라인의 나머지 부분을 설계하고 유지 관리하는 것이 훨씬 쉬워집니다.

0 조회
Back to Blog

관련 글

더 보기 »

2025년에 Python 자동화로 돈 버는 방법

개발자로서 자동화(automation)와 그것이 프로세스(processes)를 간소화하고 효율성(efficiency)을 높이며 비용(costs)을 절감할 잠재력에 익숙할 것입니다. 하지만 …