PythonでPDFを読み込みテキストを抽出する(PyMuPDF)

PythonでPDFを読み込みテキストを抽出する(PyMuPDF)
スポンサーリンク
スポンサーリンク

業務効率化・自動化の事例として、PythonでPDFを読み込みテキストを抽出する方法を解説します。

スポンサーリンク

使用ライブラリ

PythonでPDFファイルを操作するライブラリはPyMuPDF, PyPDF2, PDFminer などがあります。
それぞれのライブラリで得意とする操作が異なるため使い分けていきます。

特に日本語のPDFを読み込みテキストを抽出する場合は PyMuPDFPDFminer を利用する必要があります。PyPDF2 では日本語に対応しておらず文字化けしてしまいます。

ライブラリ使い分けをまとめると以下のようになります。

PDFライブラリ比較

・関連記事:PythonでPDFを読み込む(PyMuPDF, PyPDF2, PDFminer)

今回は PyMuPDF でPDFのテキストデータを取得する方法を解説します。

ライブラリ :PyMuPDF(公式ドキュメント
インストール:必要
 ライブラリ :openpyxl(公式ドキュメント
 インストール:必要

PyMuPDFとopenpyxlの基本的な使い方については以下の記事を参考にしてください。
・関連記事:PyMuPDFの基本的な使い方
・関連記事:PythonでExcelファイルを操作する(openpyxl)


pipコマンドでライブラリをインストールします。
・関連記事:Pythonライブラリのインストール(pipの使い方)

python -m pip install pymupdf openpyxl

Successfully installed ・・・・と表示されればインストールは成功です。(依存関係のある他のライブラリも同時にインストールされます。)

PDFファイルからテキストを抽出してExcelに出力する

1個のPDFファイルからテキストを抽出する方法です。ここでは統計局の『高等学校における「情報II」のためのデータサイエンス・データ解析入門』の第1章テキストを利用させていただきました。

PDFサンプルファイル

以下がPDFファイルのテキストデータを1ページずつ読み込み、Excelファイルに出力するプログラムです。対象のPDFファイル名は sample.pdf としています。

出力されるExcelは以下のようになります。A列にページ番号、B列にテキストを保存しています。

テキスト取得結果

プログラム解説

プログラムのポイントを解説します。

1:ライブラリ設定

PyMuPDFライブラリを使用するには、fitzをインポートします。(歴史的な理由によりこのように呼び出します)
Excel操作用にopenpyxl、列の幅を変更するAlignmentメソッドを呼び出します。
・参考記事:PythonでExcelファイルを操作する(openpyxl)

2:PDFテキストを格納するリスト作成

テキストデータ格納用のリストを作成します。

3:PDFファイルを読み込む

1行ずつ解説していきます。

filename = ‘sample.pdf’

今回はsample.pdfという名称のPDFを読み込みます。
違うファイル名を読み込む場合は、ここを読み込みたいファイル名に変更する必要があります。

doc = fitz.open(filename)

PyMuPDFのfitz.open()メソッドでPDFファイルを読み込みます。

4:1ページずつテキストデータを取得

1行ずつ解説していきます。

for page in range(len(doc)):

len(doc)でページ数を取得して、1ページずつfor文でループ処理します。ページはインデックス番号で0から始まるため注意してください。(ページ1=インデックス番号0)

for 文の使い方については以下の記事を参照してください。
・関連記事:繰り返し処理(for文)

text = doc[page].get_text()

doc[インデックス番号]でページを指定してget_text()メソッドでテキストデータを抽出します。

text = text.replace(‘\n’, ”)

文章内の改行を削除する場合は、取得したテキストの「\n」を「”」で置換します。改行を残しておきたい場合はこの行は不要です。

txt_list.append([page+1,text])

取得したテキストデータをtxt_listに追加していきます。ここではページ数と合わせてリスト内リストとして格納しています。インデックス番号をページ数に合わせる為に1を足しています。
1ページ毎に以下のようなリストになります。
[1, ‘- 1 – 第 1 章 データサイエ…いるかを理解する。 ‘]
[2, ‘- 2 – 人の動きが減少した一方で…ます。    ’]
これらのリストを追加するため、txt_listはリスト内リストになります。

txt_list =
[[1, ‘- 1 – 第 1 章 データサイエ…いるかを理解する。 ‘],
[2, ‘- 2 – 人の動きが減少した一方で…ます。    ’],

[23, ‘- 23 – 道路、橋、送電線。私た…ラ 金融業 流通業’]]

5:新しいExcelファイルを作成

新しいExcelファイルを作成してブックをwb、wbのアクティブなシートをwsと設定します。

・関連記事:PythonでExcelファイルを読み書きする(openpyxl

6:Excelの書式設定

my_alignmentに書式設定を保存します。ここではセル内で上揃えと文字の折返しを許可する設定を行っています。またB列にテキストを保存するため、読みやすくするためにセル幅を100に設定しています。好みによって数字を変更して下さい。

・参考記事:【Python×Excel】openpyxlでセルの書式設定(配置・保護・表示形式・スタイル定義)する【後編】
・参考記事:PythonでOpenPyXLを使いExcelの行と列について色々な設定をする方法

7:Excelのヘッダーを出力

ヘッダー用リストheadersを作成し、リストをfor文で処理することにより5で作成したワークシートのセルA1, A2にヘッダーを書き込みます。enumerate(リスト)を使用することでインデックス番号も同時に取得することが可能です。

・参考記事:リスト(リストの要素をfor分で取得する)

ヘッダー

8:ExcelにPDFのテキストを出力

3で取得したPDFのテキスト内容のリストtxt_listをExcelに書き出します。

ポイントを解説します。

for y, row in enumerate(txt_list):

txt_listはリスト内リストになっているため、まず1ページ毎のリストのインデックスと内容をrowに格納します。
y=0 の時のrowは以下になります。
row = [1, ‘- 1 – 第 1 章 データサイエ…いるかを理解する。 ‘]
このリストをさらに次のfor文で処理していきます。

for x, cell in enumerate(row):
    ws.cell(row= y+2, column= x+1, value=cell)
    ws.cell(row= y+2, column= x+1).alignment = my_alignment

x=0の時、row=2, column=1 → A2 にcellの内容 ‘1’ を書き込みます。
次にx=1の時、row=2, column=2 → B2 に’- 1 – 第 1 章 データサイエ…いるかを理解する。 ‘を書き込みます。
またws.cell().alignmentで上揃えと文字の折返しを適用しています。

ページ・テキスト内容

9:Excelファイルの保存

最後にExcelファイルを保存します。

xlname = filename.split(‘.’)[0] + ‘_excel.xlsx’

PDFのファイル名「sample.pdf」から拡張子抜きの文字列を取得し、保存するファイル名をsample_excel.xlsxと設定します。
filename.split('.') で [‘sample’, ‘pdf’] のリストを取得し[0]で1番目の要素を取り出しています。

・関連記事:文字列処理ー文字列の分割(split)

wb.save(xlname)

設定したファイル名でExcelファイルを保存します。

PythonでPDFのテキストを抽出する方法を解説しました。

・関連記事:PythonでPDFを読み込む(PyMuPDF, PyPDF2, PDFminer)
・関連記事:PythonでPDFファイルの画像を抽出する