파이썬으로 폴더 안의 모든 PDF 파일에서 텍스트 한 번에 추출하기

폴더에 PDF 파일이 수십 개씩 쌓여있을 때 하나하나 열어서 복사하는 건 정말 귀찮은 일이에요. 파이썬을 사용하면 단 몇 줄의 코드로 폴더 안의 모든 PDF에서 텍스트를 자동으로 추출할 수 있어요.


노트북 화면에서 PDF 문서를 처리하는 코딩 작업을 표현한 일러스트


필요한 라이브러리 설치하기


터미널을 열고 다음 명령어로 필요한 라이브러리를 설치해요.


pip install pdfplumber
pip install PyPDF2


pdfplumber로 폴더 내 모든 PDF 텍스트 추출하기


pdfplumber는 텍스트와 표를 동시에 추출할 수 있어서 복잡한 PDF 처리에 적합해요. 다음 코드로 폴더 안의 모든 PDF를 한 번에 처리할 수 있어요.


import os
import pdfplumber

def extract_all_pdfs_with_pdfplumber(input_folder, output_folder):
    # 출력 폴더가 없으면 생성
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    # 폴더 내 모든 파일 확인
    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.pdf'):
            pdf_path = os.path.join(input_folder, filename)
            
            # 텍스트 추출
            all_text = ""
            try:
                with pdfplumber.open(pdf_path) as pdf:
                    # 모든 페이지에서 텍스트 추출
                    for page in pdf.pages:
                        text = page.extract_text()
                        if text:
                            all_text += f"--- 페이지 {page.page_number} ---\n"
                            all_text += text + "\n\n"
                
                # 텍스트 파일로 저장
                output_filename = filename.replace('.pdf', '.txt')
                output_path = os.path.join(output_folder, output_filename)
                
                with open(output_path, 'w', encoding='utf-8') as f:
                    f.write(all_text)
                
                print(f"처리 완료: {filename}")
                
            except Exception as e:
                print(f"오류 발생 ({filename}): {str(e)}")

# 사용 예시
extract_all_pdfs_with_pdfplumber('/Users/사용자명/Desktop/PDF폴더', 
                                 '/Users/사용자명/Desktop/추출결과')


PyPDF2로 빠르게 텍스트 추출하기


PyPDF2는 단순 텍스트 추출에 특화되어 있어서 속도가 빠르고 가벼워요. 표나 복잡한 레이아웃이 없는 PDF라면 이 방법이 더 효율적이에요.


import os
from PyPDF2 import PdfReader

def extract_all_pdfs_with_pypdf2(input_folder, output_folder):
    # 출력 폴더가 없으면 생성
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    # 폴더 내 모든 PDF 파일 처리
    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.pdf'):
            pdf_path = os.path.join(input_folder, filename)
            
            try:
                # PDF 읽기
                reader = PdfReader(pdf_path)
                all_text = ""
                
                # 모든 페이지에서 텍스트 추출
                for i, page in enumerate(reader.pages):
                    text = page.extract_text()
                    if text:
                        all_text += f"--- 페이지 {i + 1} ---\n"
                        all_text += text + "\n\n"
                
                # 텍스트 파일로 저장
                output_filename = filename.replace('.pdf', '.txt')
                output_path = os.path.join(output_folder, output_filename)
                
                with open(output_path, 'w', encoding='utf-8') as f:
                    f.write(all_text)
                
                print(f"처리 완료: {filename}")
                
            except Exception as e:
                print(f"오류 발생 ({filename}): {str(e)}")

# 사용 예시
extract_all_pdfs_with_pypdf2('/Users/사용자명/Desktop/PDF폴더', 
                             '/Users/사용자명/Desktop/추출결과')


텍스트와 표를 동시에 추출하는 고급 방법


많은 PDF 문서에는 텍스트와 표가 섞여 있어요. pdfplumber를 사용하면 이 둘을 동시에 추출해서 각각 다른 파일로 저장할 수 있어요.


import os
import pdfplumber
import pandas as pd

def extract_text_and_tables(input_folder, output_folder):
    # 출력 폴더 생성
    text_folder = os.path.join(output_folder, 'texts')
    table_folder = os.path.join(output_folder, 'tables')
    
    for folder in [text_folder, table_folder]:
        if not os.path.exists(folder):
            os.makedirs(folder)
    
    # 모든 PDF 파일 처리
    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.pdf'):
            pdf_path = os.path.join(input_folder, filename)
            base_name = filename.replace('.pdf', '')
            
            try:
                with pdfplumber.open(pdf_path) as pdf:
                    all_text = ""
                    table_count = 0
                    
                    for page_num, page in enumerate(pdf.pages):
                        # 텍스트 추출
                        text = page.extract_text()
                        if text:
                            all_text += f"--- 페이지 {page_num + 1} ---\n"
                            all_text += text + "\n\n"
                        
                        # 표 추출
                        tables = page.extract_tables()
                        for table_idx, table in enumerate(tables):
                            if table:
                                # 표를 pandas DataFrame으로 변환
                                df = pd.DataFrame(table)
                                
                                # CSV 파일로 저장
                                table_filename = f"{base_name}_page{page_num + 1}_table{table_idx + 1}.csv"
                                table_path = os.path.join(table_folder, table_filename)
                                df.to_csv(table_path, index=False, encoding='utf-8-sig')
                                
                                table_count += 1
                    
                    # 텍스트 파일 저장
                    text_path = os.path.join(text_folder, f"{base_name}.txt")
                    with open(text_path, 'w', encoding='utf-8') as f:
                        f.write(all_text)
                    
                    print(f"처리 완료: {filename} (표 {table_count}개 추출)")
                    
            except Exception as e:
                print(f"오류 발생 ({filename}): {str(e)}")

# 사용 예시
extract_text_and_tables('/Users/사용자명/Desktop/PDF폴더',
                       '/Users/사용자명/Desktop/추출결과')


특정 페이지만 추출하기


때로는 모든 페이지가 아닌 특정 페이지만 추출하고 싶을 때가 있어요. 다음 코드로 원하는 페이지만 선택적으로 추출할 수 있어요.


import os
import pdfplumber

def extract_specific_pages(input_folder, output_folder, page_ranges):
    """
    page_ranges: 딕셔너리 형태 {'파일명.pdf': [1, 3, 5]} 또는 {'파일명.pdf': range(1, 6)}
    """
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    for filename, pages in page_ranges.items():
        pdf_path = os.path.join(input_folder, filename)
        
        if os.path.exists(pdf_path):
            try:
                with pdfplumber.open(pdf_path) as pdf:
                    selected_text = ""
                    
                    for page_num in pages:
                        # 페이지 번호는 0부터 시작
                        if 0 <= page_num - 1 < len(pdf.pages):
                            page = pdf.pages[page_num - 1]
                            text = page.extract_text()
                            
                            if text:
                                selected_text += f"--- 페이지 {page_num} ---\n"
                                selected_text += text + "\n\n"
                    
                    # 저장
                    output_filename = filename.replace('.pdf', '_selected.txt')
                    output_path = os.path.join(output_folder, output_filename)
                    
                    with open(output_path, 'w', encoding='utf-8') as f:
                        f.write(selected_text)
                    
                    print(f"처리 완료: {filename}")
                    
            except Exception as e:
                print(f"오류 발생 ({filename}): {str(e)}")

# 사용 예시
page_ranges = {
    'document1.pdf': [1, 2, 3],  # 1, 2, 3페이지만
    'document2.pdf': range(5, 11),  # 5~10페이지
    'document3.pdf': [1, 10, 20]  # 1, 10, 20페이지만
}

extract_specific_pages('/Users/사용자명/Desktop/PDF폴더',
                      '/Users/사용자명/Desktop/추출결과',
                      page_ranges)


한글 PDF 처리 시 주의사항


한글이 포함된 PDF를 처리할 때는 인코딩 설정이 중요해요. 파일을 저장할 때 반드시 utf-8 인코딩을 사용하고, CSV 파일의 경우 utf-8-sig를 사용하면 엑셀에서도 한글이 깨지지 않아요.


# 텍스트 파일 저장 시
with open(output_path, 'w', encoding='utf-8') as f:
    f.write(text)

# CSV 파일 저장 시 (엑셀에서 열 때 한글 깨짐 방지)
df.to_csv(output_path, index=False, encoding='utf-8-sig')


대용량 PDF 폴더 처리를 위한 진행 상황 표시


PDF 파일이 많을 때는 진행 상황을 확인하고 싶어요. tqdm 라이브러리를 사용하면 진행률을 시각적으로 볼 수 있어요.


import os
import pdfplumber
from tqdm import tqdm

def extract_with_progress(input_folder, output_folder):
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    
    # PDF 파일 목록 가져오기
    pdf_files = [f for f in os.listdir(input_folder) if f.lower().endswith('.pdf')]
    
    # 진행률 표시와 함께 처리
    for filename in tqdm(pdf_files, desc="PDF 처리 중"):
        pdf_path = os.path.join(input_folder, filename)
        
        try:
            with pdfplumber.open(pdf_path) as pdf:
                all_text = ""
                
                for page in pdf.pages:
                    text = page.extract_text()
                    if text:
                        all_text += text + "\n\n"
                
                # 저장
                output_filename = filename.replace('.pdf', '.txt')
                output_path = os.path.join(output_folder, output_filename)
                
                with open(output_path, 'w', encoding='utf-8') as f:
                    f.write(all_text)
                    
        except Exception as e:
            print(f"\n오류 발생 ({filename}): {str(e)}")

# 사용 예시
extract_with_progress('/Users/사용자명/Desktop/PDF폴더',
                     '/Users/사용자명/Desktop/추출결과')


pdfplumber와 PyPDF2 선택 기준


두 라이브러리 중 어떤 걸 선택해야 할지 고민이라면 다음 기준을 참고하세요.


pdfplumber를 선택해야 할 때:

  • 표(테이블) 데이터 추출이 필요할 때
  • 텍스트의 위치나 레이아웃 정보가 중요할 때
  • 복잡한 구조의 PDF를 다룰 때
  • 정확도가 속도보다 중요할 때


PyPDF2를 선택해야 할 때:

  • 단순히 텍스트만 빠르게 추출하고 싶을 때
  • 대량의 PDF를 처리해야 할 때
  • 메모리 사용량을 최소화하고 싶을 때
  • PDF 파일 자체를 조작(병합, 분할, 회전)해야 할 때


실제로 사용해보면 pdfplumber가 한글 PDF 처리에서 더 안정적인 결과를 보여주는 경우가 많아요. 특히 표가 포함된 문서라면 pdfplumber가 훨씬 유용해요.


파이썬으로 노션 데이터베이스에 CSV 파일 업로드하는 방법