PythonでPDFMinerを使用してPDFファイルからテキストを抽出しますか?


89

PythonでPDFMinerを使用してPDFファイルからテキストを抽出する方法に関するドキュメントまたは例を探しています。

PDFMinerがAPIを更新したようで、私が見つけたすべての関連する例には古いコードが含まれています(クラスとメソッドが変更されています)。PDFファイルからテキストを抽出するタスクを簡単にすることがわかったライブラリは、古いPDFMiner構文を使用しているため、これを行う方法がわかりません。

現状では、ソースコードを調べて、理解できるかどうかを確認しています。


1
stackoverflow.com/help/how-to-askstackoverflow.com/help/mcveを確認し、回答を更新して、より適切な形式でガイドラインに準拠するようにしてください。
パーカー

2.7.xと3.xxのどちらのPythonディストリビューションを使用していますか?Python 3.xxでは機能しないことを作成者が明示的に詳述していることに注意してPDFminerください。これが、importエラーが発生する理由である可能性があります。pdfminer3kその場合は、前述のライブラリの永続的なPython 3インポートであるため、使用する必要があります。
NullDev 2014年

@Nanashi、申し訳ありませんが、Pythonバージョンを追加するのを忘れました。2.7なので、問題ありません。私はソースコードを調べていましたが、いくつかのものが再構築されたようです。そのため、インポートが壊れています。PDFMinerのドキュメントも見つからないか、それを処理しているだけです:(
DuckPuncher 2014年

文字通りPDFminerGitHubからインストールしたところですが、正常にインポートされます。コードを投稿して、完全なエラートレースバックも投稿できますか?
NullDev 2014年

@Nanashi、最初の質問で言ったように、PDFMinerに依存するライブラリは、インポートを完了する前に、私が見つけた例とともに壊れます。これはPDFMinerの問題ではありません。これは、ドキュメント、またはPDFMinerの使用方法の例を探している私です。私が見つけることができるものはすべて、PDFMinerの古い構文を使用しています。わかりやすくするために、質問を編集しました。必要以上に混乱させたと思います。申し訳ありません。
DuckPuncher 2014年

回答:


184

これは、現在のバージョンの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ライブラリを使用しました。


2
正常に動作しますが、たとえば名前のスペースをどのように処理できますか?1つの列に名と
rRyef3xの

2
現在、次のコードでインポートエラーが発生しています:ImportError: 'pdfminer.pdfpage'という名前のモジュールがありません
Jeffrey Swan

1
おかげでそれはpythonv2.7.12とubuntu16.04で動作しますが、私のサンプルpdfにはエンコードの問題があるため、エンコードutf-8でpdfドキュメントをロードする方が良いでしょう。utf-8でエンコードした後にこれを試してください。問題... import sys reload(sys) sys.setdefaultencoding('utf-8')
sib10

2
@DuckPuncher、それは今でも機能していますか?動作させるには、file(path, 'rb')を `open(path、 'rb')に変更する必要がありました。
2017年

2
まだPython3.7ユーザーのために働いています。pdfminer.six == 20181108パッケージをインストールしました。私の場合、これまでのところ最良の解決策であり、私は多くの解決策を比較しました。
aze45sq6d

30

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」という名前のモジュールがありません私はPython3.6を使用しています
Atti

@Attiは、念のため、pdfminer2がインストールされていることを確認してください。別のパッケージpdfminerがあります(私はこれが嫌いです)。pip3フリーズを実行すると、pdfminer2 == 20151206バージョンで機能します。
juan Isaza 2017

5
おかげで私はそれを最終的に機能させました、私はconda forgeからpdfminer.sixをインストールしました
Atti

8
Python 3の場合、pdfminer.sixが推奨パッケージです-github.com/pdfminer/pdfminer.six
Mike Driscoll

これはまだ最新ですか。同じImportError:メッセージが表示されます

14

これは、Python3でPDFminer6を使用して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(f)

すでにメモリにあるPDFを使用する

PDFがすでにメモリにある場合、たとえば、リクエストライブラリを使用してWebから取得した場合、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にも大きなフットプリントがあり、GCCやその他のものをインストールする必要があるpycryptodomeが必要であり、AlpineLinuxの最小限のインストールDockerイメージを80MBから350MBにプッシュします。PyPDF2は、ストレージに目立った影響はありません。


このアプローチは、前回の更新以降に壊れている可能性があります。現在、ImportError: cannot import name 'open_filename' from 'pdfminer.utils'実行時にエラーが発生しますfrom pdfminer.high_level import extract_text
さらに読む

1
更新:新しいvenvを作成し、pdfminer.sixを再インストールすることで、これを修正しました。私が以前に試した他のpdfパッケージの1つが何らかの形で干渉していたと思います。
さらに読む

11

完全な開示、私は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())

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

NitroProツールを使用して変換できるPDFファイルがあります。ただし、ここに投稿されたコードを使用して同じPDFを変換しようとすると、アクセス許可エラーがあることを示唆する出力が表示されます。出力は次のとおりです:( 'SAGE SocialScienceCollectionsから。AllRightsReserved。\ 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 with open(file、 'rb')as stream:[...]
RodrigoFormighieri20年

このファイルをテーブル/パンダとして理想的に取得できますか?groupe-psa.com/en/publication/monthly-world-sales-march-2020
Nono London
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.