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


87

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

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

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


1
stackoverflow.com/help/how-to-askstackoverflow.com/help/mcve를 확인하고 더 나은 형식으로 가이드 라인에 맞도록 답변을 업데이트하세요.
Parker

2.7.x 또는 3.xx 중 어떤 Python 배포를 사용하고 있습니까? 작성자 는 Python 3.xx에서 작동하지 않는 내용을 명시 적으로 자세히 설명했습니다. PDFminer이것이 import오류 가 발생 하는 이유 일 수 있습니다. pdfminer3k해당 라이브러리의 스탠딩 Python 3 가져 오기이므로 사용해야 합니다.
NullDev 2014 년

@Nanashi, 죄송합니다. Python 버전을 추가하는 것을 잊었습니다. 2.7이므로 문제가 아닙니다. 나는 소스 코드를 살펴 보았고 그들이 수입이 깨지는 이유를 재구성 한 것처럼 보입니다. PDFMiner에 대한 문서를 찾을 수 없거나 그 작업을 수행 할 것입니다. (
DuckPuncher

나는 말 그대로 PDFminerGitHub에서 설치 했으며 잘 가져옵니다. 친절하게 코드를 게시하고 전체 오류 추적을 게시 할 수 있습니까?
NullDev 2014 년

@Nanashi, 내가 원래 질문에서 말했듯이 PDFMiner에 의존하는 라이브러리는 내가 찾을 수있는 모든 예와 함께 가져 오기를 완료하기 전에 중단됩니다. 이것은 PDFMiner 문제가 아닙니다. 이것은 문서를 찾고 있거나 PDFMiner를 사용하는 방법의 예입니다. 내가 찾을 수있는 모든 것은 PDFMiner에 대한 이전 구문을 사용하는 것입니다. 나는 계속해서 명확성을 위해 내 질문을 편집했습니다. 필요했던 것보다 더 혼란스럽게 만들었다 고 생각합니다. 미안합니다.
DuckPuncher

답변:


181

다음은 현재 버전의 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 라이브러리를 사용했습니다 .


2
잘 작동하지만 예를 들어 이름의 공백을 어떻게 처리 할 수 ​​있습니까? 한 열에 성과 이름이있는 4 개의 열을 포함하는 pdf가 있다고 가정합니다. 이제 한 행에 이름과 한 행에 성으로 구문 분석됩니다. 여기에 예제가 있습니다. docdro.id/rRyef3x
Deusdeorum

2
현재이 코드에서 가져 오기 오류가 발생합니다. ImportError : 'pdfminer.pdfpage'라는 모듈이 없습니다.
Jeffrey Swan

1
감사합니다 python v2.7.12 및 우분투 16.04에서 작동하지만 샘플 pdf에는 인코딩 문제가 있기 때문에 utf-8 인코딩으로 pdf 문서를로드하는 것이 더 낫습니다. 문제 ... import sys reload(sys) sys.setdefaultencoding('utf-8')
sib10

2
@DuckPuncher, 아직 작동 중입니까? 나는 변경했습니다 file(path, 'rb')작업에 광산을 얻기 위해 개방 (경로, 'RB')`에.
Craned

2
Python3.7 사용자를 위해 계속 작동합니다. pdfminer.six == 20181108 패키지를 설치했습니다. 지금까지 내 사례에 가장 적합한 솔루션과 수많은 솔루션을 비교했습니다.
aze45sq6d

29

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

1
그것은 나를 위해 작동하지 않습니다 : ModuleNotFoundError : 'pdfminer.pdfpage'라는 모듈이 없습니다. 저는 파이썬 3.6을 사용하고 있습니다
Atti

@Atti는 다른 패키지 pdfminer가 있기 때문에 pdfminer2가 설치되어 있는지 확인하십시오 (나는 이것을 싫어합니다). pip3 동결을 할 때 pdfminer2 == 20151206 버전에서 작동합니다.
후안 Isaza

5
내가 그것을 결국 작업있어 덕분에, 내가 CONDA 단조에서 pdfminer.six 설치
ATTI

8
Python 3의 경우 pdfminer.six가 권장 패키지입니다 -github.com/pdfminer/pdfminer.six
Mike Driscoll

이것은 여전히 ​​최신입니다. 동일한 ImportError:메시지가 나타납니다

12

이것은 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는 스토리지에 눈에 띄는 영향을 미치지 않습니다.


9

전체 공개, 저는 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())

0

이 코드는 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

Nitro Pro 도구를 사용하여 변환 할 수있는 PDF 파일이 있습니다. 그러나 여기에 게시 된 코드를 사용하여 동일한 PDF를 변환하려고하면 권한 오류가 있음을 나타내는 출력이 표시됩니다. 출력은 다음과 같습니다. ( 'SAGE Social Science 컬렉션에서. All Rights Reserved. \ n \ n \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c \ x0c ')
b00kgrrl

파일 스트림이란 무엇입니까?
Vincent

@Vincent with open (file, 'rb') as stream : [...]
Rodrigo Formighieri

이 파일을 테이블 / 팬더로 이상적으로 얻을 수 있습니까? groupe-psa.com/en/publication/monthly-world-sales-march-2020
Nono London
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.