본문 바로가기

Data science/크롤링

PDF 파싱

import sys

from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams, LTContainer, LTTextBox
from pdfminer.pdfinterp import PDFPageInterpreter, PDFResourceManager
from pdfminer.pdfpage import PDFPage

def find_textboxes_recursively(layout_obj):
    '''
    재귀적으로 텍스트 박스(LTTextBox)를 찾고
    텍스트 박스들을 리스트로 반환한다.
    '''

    # LTTextBox를 상속받은 객체의 경우 리스트에 곧바로 넣어서 반환한다.
    if isinstance(layout_obj, LTTextBox):
        return [layout_obj]

    # LTContainer를 상속받은 객체의 경우 자식 요소를 포함하고 있다는 의미
    # 재귀적으로 자식 요소를 계속 찾는다.
    if isinstance(layout_obj, LTContainer):
        boxes = []
        for child in layout_obj:
            boxes.extend(find_textboxes_recursively(child))
        return boxes
    # 아무것도 없으면 빈 리스트를 반환
    return []

# 공유 리소스를 관리하는 리소스 매니저를 생성한다.
laparams = LAParams()
resource_manager = PDFResourceManager()

# 페이지를 모으는 PageAggregator 객체를 생성한다.
device = PDFPageAggregator(resource_manager, laparams=laparams)

# Interpreter 객체를 생성한다.
interpreter = PDFPageInterpreter(resource_manager, device)

# 파일을 바이너리 형식으로 읽어 들인다.
with open(sys.argv[1], 'rb') as f:
    # PDFPage.get_pages로 파일 객체를 지정한다.
    # PDFPage 객체를 차례대로 추출한다.
    # 키워드 매개변수인 pagenos로 처리할 페이지 번호(0-index)를 리스트 형식으로 지정할 수도 있다.
    for page in PDFPage.get_pages(f):
        # 페이지 처리
        interpreter.process_page(page)
        # LTPage 객체를 추출
        layout = device.get_result()
        # 페이지 내부의 텍스트 박스를 리스트로 추출
        boxes = find_textboxes_recursively(layout)
        # 텍스트 박스를 왼쪽 위의 좌표부터 차례대로 정렬한다.
        # y1(Y 좌표)는 위에 있을수록 크므로 음수로 변환하게 해서 비교
        boxes.sort(key=lambda b: (-b.y1, b.x0))
        for box in boxes:
            # 읽기 쉽게 선을 출력
            print('-' * 10)
            # 텍스트 박스의 내용을 출력
            print(box.get_text().strip())

'Data science > 크롤링' 카테고리의 다른 글

SelectorList 객체 메서드 정리  (0) 2024.10.07
유튜브 크롤링  (0) 2024.09.27
Mac API 환경변수 설정  (0) 2024.09.27
email 보내기  (0) 2024.09.23
Schema(크롤링 대상의 변화)  (0) 2024.09.23