[python] Python에서 PDFMiner를 사용하여 PDF 파일에서 텍스트 추출?

Python과 함께 PDFMiner를 사용하여 PDF 파일에서 텍스트를 추출하는 방법에 대한 문서 또는 예제를 찾고 있습니다.

PDFMiner가 API를 업데이트하고 내가 찾은 모든 관련 예제에 오래된 코드가 포함되어있는 것 같습니다 (클래스와 메서드가 변경됨). PDF 파일에서 텍스트를 더 쉽게 추출하는 작업을 수행하는 라이브러리는 이전 PDFMiner 구문을 사용하고 있으므로이 작업을 수행하는 방법을 잘 모르겠습니다.

그대로, 나는 그것을 알아낼 수 있는지 확인하기 위해 소스 코드를보고 있습니다.



답변

다음은 현재 버전의 PDFMiner를 사용하여 PDF 파일에서 텍스트를 추출하는 작업 예입니다 (2016 년 9 월).

from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from io import StringIO

def convert_pdf_to_txt(path):
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    fp = open(path, 'rb')
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    password = ""
    maxpages = 0
    caching = True
    pagenos=set()

    for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
        interpreter.process_page(page)

    text = retstr.getvalue()

    fp.close()
    device.close()
    retstr.close()
    return text

PDFMiner의 구조가 최근 변경되었으므로 PDF 파일에서 텍스트를 추출하는 데 사용할 수 있습니다.

편집 : 2018 년 6 월 7 일부터 계속 작동합니다. Python 버전 3.x에서 확인되었습니다.

편집 :이 솔루션은 2019 년 10 월 3 일에 Python 3.7에서 작동합니다. 저는 pdfminer.six2018 년 11 월에 출시 된 Python 라이브러리를 사용했습니다 .


답변

DuckPuncher의 훌륭한 답변, Python3의 경우 pdfminer2를 설치하고 다음을 수행하십시오.

import io

from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage


def convert_pdf_to_txt(path):
    rsrcmgr = PDFResourceManager()
    retstr = io.StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    fp = open(path, 'rb')
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    password = ""
    maxpages = 0
    caching = True
    pagenos = set()

    for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages,
                                  password=password,
                                  caching=caching,
                                  check_extractable=True):
        interpreter.process_page(page)



    fp.close()
    device.close()
    text = retstr.getvalue()
    retstr.close()
    return text


답변

이것은 Python3에서 PDFminer 6을 사용하여 2020 년 5 월에 작동합니다.

패키지 설치

$ pip install pdfminer.six

패키지 가져 오기

from pdfminer.high_level import extract_text

디스크에 저장된 PDF 사용

text = extract_text('report.pdf')

또는 :

with open('report.pdf','rb') as f:
    text = extract_text(open('report.pdf','rb'))

이미 메모리에있는 PDF 사용

PDF가 이미 메모리에있는 경우 (예 : 요청 라이브러리를 사용하여 웹에서 검색 한 경우) 라이브러리를 사용하여 스트림으로 변환 할 수 있습니다 io.

import io

response = requests.get(url)
text = extract_text(io.BytesIO(response.content))

PyPDF2와 비교 한 성능 및 신뢰성

PDFminer.six는 PyPDF2 (특정 유형의 PDF에서는 실패 함), 특히 PDF 버전 1.7보다 더 안정적으로 작동합니다.

그러나 PDFminer.six를 사용한 텍스트 추출은 PyPDF2보다 6 배 더 느립니다.

timeit15 “MBP (2018)에서 텍스트 추출 시간을 지정 하고 10 페이지 PDF로 추출 기능 (파일 열기 없음 등) 만 시간을 지정하고 다음과 같은 결과를 얻었습니다.

PDFminer.six: 2.88 sec
PyPDF2:       0.45 sec

pdfminer.six는 또한 pycryptodome을 필요로하므로 Alpine Linux에서 최소 설치 도커 이미지를 80MB에서 350MB로 밀어 넣는 GCC 및 기타 설치가 필요한 pycryptodome이 필요합니다. PyPDF2는 스토리지에 눈에 띄는 영향을 미치지 않습니다.


답변

전체 공개, 저는 pdfminer.six의 관리자 중 한 명입니다.

요즘에는 필요에 따라 PDF에서 텍스트를 추출하는 여러 API가 있습니다. 배후에서 이러한 모든 API는 레이아웃을 구문 분석하고 분석하는 데 동일한 논리를 사용합니다.

커맨드 라인

텍스트를 한 번만 추출하려면 명령 줄 도구 pdf2txt.py를 사용할 수 있습니다.

$ pdf2txt.py example.pdf

고급 API

Python으로 텍스트를 추출하려는 경우 고급 API를 사용할 수 있습니다. 이 접근 방식은 많은 PDF에서 프로그래밍 방식으로 텍스트를 추출하려는 경우 사용할 수있는 솔루션입니다.

from pdfminer.high_level import extract_text

text = extract_text('samples/simple1.pdf')

구성 가능한 API

결과 객체를 처리하는 데 많은 유연성을 제공하는 구성 가능한 API도 있습니다. 예를 들어이를 사용하여 자체 레이아웃 알고리즘을 구현할 수 있습니다. 이 방법은 다른 답변에서 제안되지만 pdfminer.six의 작동 방식을 사용자 정의해야 할 때만 권장합니다.

from io import StringIO

from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.pdfparser import PDFParser

output_string = StringIO()
with open('samples/simple1.pdf', 'rb') as in_file:
    parser = PDFParser(in_file)
    doc = PDFDocument(parser)
    rsrcmgr = PDFResourceManager()
    device = TextConverter(rsrcmgr, output_string, laparams=LAParams())
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    for page in PDFPage.create_pages(doc):
        interpreter.process_page(page)

print(output_string.getvalue())


답변

이 코드는 python 3 용 pdfminer로 테스트되었습니다 (pdfminer-20191125).

from pdfminer.layout import LAParams
from pdfminer.converter import PDFPageAggregator
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.layout import LTTextBoxHorizontal

def parsedocument(document):
    # convert all horizontal text into a lines list (one entry per line)
    # document is a file stream
    lines = []
    rsrcmgr = PDFResourceManager()
    laparams = LAParams()
    device = PDFPageAggregator(rsrcmgr, laparams=laparams)
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    for page in PDFPage.get_pages(document):
            interpreter.process_page(page)
            layout = device.get_result()
            for element in layout:
                if isinstance(element, LTTextBoxHorizontal):
                    lines.extend(element.get_text().splitlines())
    return lines


답변