【Python】pdfminer.six:PDFからテキストを取得・抽出する

時計 2021.08.05 / 時計

【Python】pdfminer.six:PDFからテキストを取得・抽出する

本記事ではPython外部ライブラリであるpdfminer.sixを使った、PDFからテキストを取得・抽出する方法について解説します。

PDFはビジネスで最もやり取りの多いファイル形式の1つです。
PDFをプログラムで操作できるということは、業務時間を削減する可能性が大いにありま

PythonにはPDFを操作する様々な方法が用意されています。

ここではpdfminer.sixを使ってPDFからテキストを取得・抽出する非常に簡単な方法について解説しています。

本記事を通して以下の知識を学べます。

学べる知識
  • pdfminer.sixについて
  • PDFからテキストを抽出:extract_text()関数
  • PDFからテキストを抽出:extract_text_to_fp()関数
  • extract_text()でエラーが発生した場合の対処法

PDFからテキストを取得・抽出する

PDFとは

PDF(Portable Document Format)はビジネスから日常まで様々な場面で使用されるファイル形式です。

PDFファイルは相手がどんな端末でも情報を共有できるため、非常に優秀なファイル形式ではありますが、プログラムで扱おうと思うとやっかいなファイルではあります。

プログラムでPDFファイルのテキストを抽出すると、正確に抽出できないこともあります。また抽出する方法によっては、特定のPDFファイルに対しては全く抽出できない場合もあります。

PythonでPDFからテキストを抽出するには

PythonでPDFファイルからテキストを抽出する方法はいくつか存在します。

本記事ではpdfminer.sixを使ったテキストの抽出方法を解説しますが、以下記事ではPyPDF2を使ったテキストの抽出方法を解説しています。

私の経験上、PyPDF2でテキスト抽出がうまくいかないPDFが、pdfminer.sixではテキスト抽出が成功するということがあります。

例えば以下記事では、PyPDF2ではEOF marker not foundエラーが発生しました。
しかしpdfminerではエラーが発生することがなく、PDFからテキストを問題なく取得することができました。

そのためPDFからテキストを抽出する複数の方法をマスターし、使い分けることはとても有用です。

pdfminer.six

pdfminer.sixとは

pdfminer.sixはPDFファイルからテキスト情報を抽出する機能を有するPythonモジュールです。

pdfminer.sixはPDFMinerから派生したモジュールです。
しかしPDFMinerはすでに開発はストップしており、現在ではpdfminer.sixを使用します。

Pythonのバージョンは3.6以上が必要になります。バージョン3.4や3.5は非推奨であると公式に記載があります。

まずはご自身の環境がpdfminer.sixを使用できるか確認してみてください。

> python -V
Python 3.7.6

pdfminer.sixの特徴

pdfminer.sixの特徴を以下に記します。

  • PDFからテキスト情報を抽出
  • PDFから画像(JPGやBitmapなど)、目次、タグ付けコンテンツを抽出
  • RC4やAESの暗号化をサポート
  • 日本語、中国語、韓国語をサポート

pipインストール

pdfminer.sixは標準ではインストールされていないため、pipコマンドでインストールする必要があります。

> pip install pdfminer.six

2021年8月現在では、バージョン20201018が最新バーションです。

> pip list
pdfminer.six	20201018

スクリプトでは次の方法でpdfminer.sixのバージョン確認ができます。

> import pdfminer
> print(pdfminer.__version__)
20201018

pdfminer.sixでPDFからテキスト抽出を行う

pdfminer.sixにはPDFからテキスト抽出を行う関数を2つ用意されています。

  • extract_text()
  • extract_text_to_fp()

上記の関数について次項から解説していきます。

extract_text()

extract_textはhigh-level APIが提供する関数であり、
PDFからテキストを抽出する最もシンプルな方法です。

構文は次のようになります。

構文

pdfminer.high_level.extract_text(pdf_file, password='', page_numbers=None, maxpages=0, caching=True, codec='utf-8', laparams=None)

パラメーター 説明
pdf_file ファイルパス
password 暗号化されたPDFを解除するためのパスワード
page_numbers 抽出するページ数のリスト
maxpages 解析するページの最大数
caching リソースをキャッシュするか
codec テキストデコーディングコード
laparams pdfminer.layoutのLAParamsオブジェクト。 Noneの場合、うまく働くデフォルト設定を使用

extract_text()は次のように使用します。

from pdfminer.high_level import extract_text
text = extract_text('office54.pdf')
print(text)

1行目ではpdfminer.high_levelからextract_textをインポート、2行目ではextract_textを用いて指定したパスのPDFからテキストの抽出、3行目で抽出したテキストを表示しています。

extract_text_to_fp()

extract_textはhigh-level APIが提供する関数であり、
PDFからテキストを抽出し、特定のオブジェクトにテキスト情報を渡します。

構文は次のようになります。

構文

pdfminer.high_level.extract_text_to_fp(inf, outfp, output_type='text', codec='utf-8', laparams=None, maxpages=0, page_numbers=None, password='', scale=1.0, rotation=0, layoutmode='normal', output_dir=None, strip_control=False, debug=False, disable_caching=False, **kwargs)

extract_text_to_fpには様々なパラメーターが用意されていますが、基本的にはinfとoutfpを指定します。

infにはPDFファイルをファイルハンドラー(open()で開いたオブジェクト)で指定、outfpにはテキストを書き込むためのファイルライクオブジェクト(StringIO)を指定します。

以下にextract_text_to_fpの使用例を記載します。

from pdfminer.high_level import extract_text_to_fp
from io import StringIO

fp = open(path, "rb")
outfp = StringIO()
extract_text_to_fp(fp, outfp)
print(outfp.getvalue().strip())

StringIOでは文字列をメモリにバッファします。
これにより文字列をファイルオブジェクトのように扱うことができ、readやwriteなどのファイル操作ができます。

extract_text_to_fp()関数では第二引数にStringIOオブジェクトを指定することで、抽出したテキストをStringIOオブジェクトに渡しているのです。

extract_text()でエラー発生

PDFのテキスト抽出にextract_text()メソッドを使用すると以下のエラーが発生することがありました。

エラー

from pdfminer.high_level import extract_text ImportError: cannot import name 'extract_text' from 'pdfminer.high_level'

from pdfminer.high_level import extract_text

text = extract_text('office54.pdf')
print(text)

エラー内容を見ると、pdfminer.high_levelからextract_textをインポートできないと記載されています。

そこでLib\site-packages\pdfminerフォルダ内のhigh_level.pyを確認すると、なんとextract_text()関数が存在しませんでした。

この問題を解決するために以下の流れでpdfminer.sixを再度インストールしました。

  1. pip uninstall pdfminer.sixを実行し、アンインストールを行う
  2. python -m pip install --upgrade pipを実行し、pipをアップグレードする
  3. pip install pdfminer.sixを実行し、インストールを行う

上記を行った後、high_level.pyを確認するとextract_text()関数がちゃんと存在していました。

もし同様のエラーが発生した場合は、pdfminer.sixの再インストールを行ってみてください。

codecエラーの発生

pdfminer.sixのpdfminer.converter.TextConverterで次のようなエラーが発生することがあります。

エラー

__init__() got an unexpected keyword argument ‘codec’

私はDjangoで作成しているWebアプリケーションで発生しました。
そのときの対処方法は以下記事を参照してください。

まとめ

本記事「【Python】pdfminer.six:PDFからテキストを取得・抽出する」はいかがでしたか。

pdfminer.sixを使えば非常に簡単にPDFからテキストを取得できることが分かったかと思います。

日本語にも対応しているので、様々なPDFで利用することができます。

ぜひpdfminer.sixを使ったアプリケーションを作成して、業務改善などに活用してみてください。