Estou procurando documentação ou exemplos sobre como extrair texto de um arquivo PDF usando PDFMiner com Python.
Parece que o PDFMiner atualizou sua API e todos os exemplos relevantes que encontrei contêm código desatualizado (classes e métodos foram alterados). As bibliotecas que descobri que facilitam a tarefa de extrair texto de um arquivo PDF estão usando a sintaxe antiga do PDFMiner, então não tenho certeza de como fazer isso.
Do jeito que está, estou apenas olhando o código-fonte para ver se consigo descobrir.
python
python-3.x
python-2.7
text-extraction
pdfminer
DuckPuncher
fonte
fonte
PDFminer
não funciona com Python 3.xx Esse pode ser o motivo de você estar recebendoimport
erros. Você deve usarpdfminer3k
nesse caso, pois é a importação Python 3 permanente da referida biblioteca.PDFminer
do GitHub e importa muito bem. Você pode gentilmente postar seu código e também o rastreamento completo do erro?Respostas:
Aqui está um exemplo prático de extração de texto de um arquivo PDF usando a versão atual do PDFMiner (setembro de 2016)
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
A estrutura do PDFMiner mudou recentemente, então isso deve funcionar para extrair texto dos arquivos PDF.
Edit : Ainda trabalhando em 7 de junho de 2018. Verificado na versão Python 3.x
Edit: A solução funciona com Python 3.7 em 3 de outubro de 2019. Usei a biblioteca Python
pdfminer.six
, lançada em novembro de 2018.fonte
import sys reload(sys) sys.setdefaultencoding('utf-8')
file(path, 'rb')
para `open (path, 'rb') para fazer o meu funcionar.excelente resposta do DuckPuncher, para Python3 certifique-se de instalar o pdfminer2 e fazer:
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
fonte
ImportError:
mensagemIsso funcionará em maio de 2020 usando PDFminer six em Python3.
Instalando o pacote
Importando o pacote
from pdfminer.high_level import extract_text
Usando um PDF salvo no disco
text = extract_text('report.pdf')
Ou alternativamente:
with open('report.pdf','rb') as f: text = extract_text(open('report.pdf','rb'))
Usando PDF já na memória
Se o PDF já estiver na memória, por exemplo, se recuperado da web com a biblioteca de solicitações, ele pode ser convertido em um fluxo usando a
io
biblioteca:import io response = requests.get(url) text = extract_text(io.BytesIO(response.content))
Desempenho e confiabilidade em comparação com PyPDF2
PDFminer.six funciona de forma mais confiável do que PyPDF2 (que falha com certos tipos de PDFs), em particular o PDF versão 1.7
No entanto, a extração de texto com PDFminer.six é significativamente mais lenta do que PyPDF2 por um fator de 6.
timeit
Cronometrei a extração de texto com um MBP de 15 "(2018), cronometrando apenas a função de extração (sem abertura de arquivo etc.) com um PDF de 10 páginas e obtive os seguintes resultados:PDFminer.six: 2.88 sec PyPDF2: 0.45 sec
O pdfminer.six também ocupa uma grande área de cobertura, exigindo pycryptodome, que precisa do GCC e de outras coisas instaladas, enviando uma imagem docker de instalação mínima no Alpine Linux de 80 MB a 350 MB. PyPDF2 não tem impacto de armazenamento perceptível.
fonte
Divulgação completa, sou um dos mantenedores do pdfminer.six.
Hoje em dia, existem várias APIs para extrair texto de um PDF, dependendo de suas necessidades. Nos bastidores, todas essas APIs usam a mesma lógica para analisar e analisar o layout.
Linha de comando
Se você deseja extrair o texto apenas uma vez, pode usar a ferramenta de linha de comando pdf2txt.py:
API de alto nível
Se você deseja extrair texto com Python, pode usar a API de alto nível. Essa abordagem é a solução ideal se você deseja extrair texto programaticamente de muitos PDFs.
from pdfminer.high_level import extract_text text = extract_text('samples/simple1.pdf')
API composable
Também há uma API composable que oferece muita flexibilidade no manuseio dos objetos resultantes. Por exemplo, você pode implementar seu próprio algoritmo de layout usando isso. Esse método é sugerido nas outras respostas, mas eu só recomendaria quando você precisar personalizar a maneira como o pdfminer.six se comporta.
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())
fonte
este código é testado com pdfminer para python 3 (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
fonte