PythonでPDFMinerを使用してPDFファイルからテキストを抽出する方法に関するドキュメントまたは例を探しています。
PDFMinerがAPIを更新したようで、私が見つけたすべての関連する例には古いコードが含まれています(クラスとメソッドが変更されています)。PDFファイルからテキストを抽出するタスクを簡単にすることがわかったライブラリは、古いPDFMiner構文を使用しているため、これを行う方法がわかりません。
現状では、ソースコードを調べて、理解できるかどうかを確認しています。
PythonでPDFMinerを使用してPDFファイルからテキストを抽出する方法に関するドキュメントまたは例を探しています。
PDFMinerがAPIを更新したようで、私が見つけたすべての関連する例には古いコードが含まれています(クラスとメソッドが変更されています)。PDFファイルからテキストを抽出するタスクを簡単にすることがわかったライブラリは、古いPDFMiner構文を使用しているため、これを行う方法がわかりません。
現状では、ソースコードを調べて、理解できるかどうかを確認しています。
PDFminer
ください。これが、import
エラーが発生する理由である可能性があります。pdfminer3k
その場合は、前述のライブラリの永続的なPython 3インポートであるため、使用する必要があります。
PDFminer
GitHubからインストールしたところですが、正常にインポートされます。コードを投稿して、完全なエラートレースバックも投稿できますか?
回答:
これは、現在のバージョンのPDFMiner(2016年9月)を使用してPDFファイルからテキストを抽出する実際の例です。
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日にPython3.7で動作しpdfminer.six
ます。2018年11月にリリースされたPythonライブラリを使用しました。
import sys reload(sys) sys.setdefaultencoding('utf-8')
file(path, 'rb')
を `open(path、 'rb')に変更する必要がありました。
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でPDFminer6を使用して2020年5月に機能します。
$ pip install pdfminer.six
from pdfminer.high_level import extract_text
text = extract_text('report.pdf')
または代わりに:
with open('report.pdf','rb') as f:
text = extract_text(f)
PDFがすでにメモリにある場合、たとえば、リクエストライブラリを使用してWebから取得した場合、io
ライブラリを使用してストリームに変換できます。
import io
response = requests.get(url)
text = extract_text(io.BytesIO(response.content))
PDFminer.sixは、PyPDF2(特定の種類のPDFでは失敗します)、特にPDFバージョン1.7よりも確実に機能します。
ただし、PDFminer.sixを使用したテキスト抽出は、PyPDF2よりも6倍遅くなります。
timeit
15 "MBP(2018)でテキスト抽出のタイミングを調整し、抽出機能のみ(ファイルを開かないなど)のタイミングを10ページのPDFで設定すると、次の結果が得られました。
PDFminer.six: 2.88 sec
PyPDF2: 0.45 sec
pdfminer.sixにも大きなフットプリントがあり、GCCやその他のものをインストールする必要があるpycryptodomeが必要であり、AlpineLinuxの最小限のインストールDockerイメージを80MBから350MBにプッシュします。PyPDF2は、ストレージに目立った影響はありません。
ImportError: cannot import name 'open_filename' from 'pdfminer.utils'
実行時にエラーが発生しますfrom pdfminer.high_level import extract_text
完全な開示、私はpdfminer.sixのメンテナーの1人です。
現在、ニーズに応じて、PDFからテキストを抽出するための複数のAPIがあります。舞台裏では、これらのAPIはすべて、レイアウトの解析と分析に同じロジックを使用しています。
(すべての例では、PDFファイルの名前がexample.pdfであると想定しています)
コマンドライン
一度だけテキストを抽出したい場合は、コマンドラインツールpdf2txt.pyを使用できます。
$ pdf2txt.py example.pdf
高レベルのAPI
Pythonでテキストを抽出する場合は、高レベルのAPIを使用できます。このアプローチは、多くのPDFからプログラムでテキストを抽出する場合の頼りになるソリューションです。
from pdfminer.high_level import extract_text
text = extract_text('example.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('example.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