業務効率化・自動化の事例として、PythonでPDFを読み込みテキストを抽出する方法を解説します。
使用ライブラリ
PythonでPDFファイルを操作するライブラリはPyMuPDF
, PyPDF2
, PDFminer
などがあります。
それぞれのライブラリで得意とする操作が異なるため使い分けていきます。
特に日本語のPDFを読み込みテキストを抽出する場合は PyMuPDF
や PDFminer
を利用する必要があります。PyPDF2
では日本語に対応しておらず文字化けしてしまいます。
ライブラリ使い分けをまとめると以下のようになります。
・関連記事:PythonでPDFを読み込む(PyMuPDF, PyPDF2, PDFminer)
今回は PyMuPDF
でPDFのテキストデータを取得する方法を解説します。
インストール:必要
インストール:必要
PyMuPDFとopenpyxlの基本的な使い方については以下の記事を参考にしてください。
・関連記事:PyMuPDFの基本的な使い方
・関連記事:PythonでExcelファイルを操作する(openpyxl)
pip
コマンドでライブラリをインストールします。
・関連記事:Pythonライブラリのインストール(pipの使い方)
Successfully installed ・・・・と表示されればインストールは成功です。(依存関係のある他のライブラリも同時にインストールされます。)
PDFファイルからテキストを抽出してExcelに出力する
1個のPDFファイルからテキストを抽出する方法です。ここでは統計局の『高等学校における「情報II」のためのデータサイエンス・データ解析入門』の第1章テキストを利用させていただきました。
以下がPDFファイルのテキストデータを1ページずつ読み込み、Excelファイルに出力するプログラムです。対象のPDFファイル名は sample.pdf
としています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | # 1:ライブラリ設定 import fitz # pymupdfライブラリ import openpyxl as px from openpyxl.styles import Alignment # 2:PDFテキストを格納するリスト作成 txt_list = [] # 3:PDFファイルを読み込む filename = 'sample.pdf' doc = fitz.open(filename) # 4:1ページずつテキストデータを取得 for page in range(len(doc)): text = doc[page].get_text() text = text.replace('\n', '') txt_list.append([page+1,text]) # 5:新しいExcelファイルを作成 wb = px.Workbook() ws = wb.active # 6:Excelの書式設定 my_alignment=Alignment(vertical='top', wrap_text=True) ws.column_dimensions['B'].width = 100 # 7:Excelのヘッダーを出力 headers = ['ページ', '内容'] for i, header in enumerate(headers): ws.cell(row=1, column=1+i, value=headers[i]) # 8:ExcelにPDFのテキストを出力 for y, row in enumerate(txt_list): 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 # 9:Excelファイルの保存 xlname = filename.split('.')[0] + '_excel.xlsx' wb.save(xlname) |
出力されるExcelは以下のようになります。A列にページ番号、B列にテキストを保存しています。
プログラム解説
プログラムのポイントを解説します。
1:ライブラリ設定
1 2 3 4 | # 1:ライブラリ設定 import fitz import openpyxl as px from openpyxl.styles import Alignment |
PyMuPDFライブラリを使用するには、fitzをインポートします。(歴史的な理由によりこのように呼び出します)
Excel操作用にopenpyxl、列の幅を変更するAlignmentメソッドを呼び出します。
・参考記事:PythonでExcelファイルを操作する(openpyxl)
2:PDFテキストを格納するリスト作成
1 2 | # 2:PDFのテキストを格納するリスト作成 txt_list = [] |
テキストデータ格納用のリストを作成します。
3:PDFファイルを読み込む
1 2 3 | # 3:PDFファイルを読み込む filename = 'sample.pdf' doc = fitz.open(filename) |
1行ずつ解説していきます。
今回はsample.pdfという名称のPDFを読み込みます。
違うファイル名を読み込む場合は、ここを読み込みたいファイル名に変更する必要があります。
PyMuPDFのfitz.open()
メソッドでPDFファイルを読み込みます。
4:1ページずつテキストデータを取得
1 2 3 4 5 | # 4:1ページずつ読み込み for page in range(len(doc)): text = doc[page].get_text() text = text.replace('\n', '') txt_list.append([page+1,text]) |
1行ずつ解説していきます。
len(doc)
でページ数を取得して、1ページずつfor文でループ処理します。ページはインデックス番号で0から始まるため注意してください。(ページ1=インデックス番号0)
for 文の使い方については以下の記事を参照してください。
・関連記事:繰り返し処理(for文)
doc[インデックス番号]でページを指定してget_text()
メソッドでテキストデータを抽出します。
文章内の改行を削除する場合は、取得したテキストの「\n」を「”」で置換します。改行を残しておきたい場合はこの行は不要です。
取得したテキストデータをtxt_listに追加していきます。ここではページ数と合わせてリスト内リストとして格納しています。インデックス番号をページ数に合わせる為に1を足しています。
1ページ毎に以下のようなリストになります。
[1, ‘- 1 – 第 1 章 データサイエ…いるかを理解する。 ‘]
[2, ‘- 2 – 人の動きが減少した一方で…ます。 ’]
これらのリストを追加するため、txt_list
はリスト内リストになります。
[[1, ‘- 1 – 第 1 章 データサイエ…いるかを理解する。 ‘],
[2, ‘- 2 – 人の動きが減少した一方で…ます。 ’],
…
[23, ‘- 23 – 道路、橋、送電線。私た…ラ 金融業 流通業’]]
5:新しいExcelファイルを作成
1 2 3 | # 5:新しいExcelファイルを作成 wb = px.Workbook() ws = wb.active |
新しいExcelファイルを作成してブックをwb、wbのアクティブなシートをwsと設定します。
・関連記事:PythonでExcelファイルを読み書きする(openpyxl)
6:Excelの書式設定
1 2 3 | # 6:Excelの書式設定 my_alignment=Alignment(vertical='top', wrap_text=True) ws.column_dimensions['B'].width = 100 |
my_alignment
に書式設定を保存します。ここではセル内で上揃えと文字の折返しを許可する設定を行っています。またB列にテキストを保存するため、読みやすくするためにセル幅を100に設定しています。好みによって数字を変更して下さい。
・参考記事:【Python×Excel】openpyxlでセルの書式設定(配置・保護・表示形式・スタイル定義)する【後編】
・参考記事:PythonでOpenPyXLを使いExcelの行と列について色々な設定をする方法
7:Excelのヘッダーを出力
1 2 3 4 | # 7:Excelのヘッダーを出力 headers = ['ページ', '内容'] for i, header in enumerate(headers): ws.cell(row=1, column=1+i, value=headers[i]) |
ヘッダー用リストheaders
を作成し、リストをfor文で処理することにより5で作成したワークシートのセルA1, A2にヘッダーを書き込みます。enumerate(リスト)
を使用することでインデックス番号も同時に取得することが可能です。
・参考記事:リスト(リストの要素をfor分で取得する)
8:ExcelにPDFのテキストを出力
1 2 3 4 5 | # 8:ExcelにPDFのテキストを出力 for y, row in enumerate(txt_list): 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 |
3で取得したPDFのテキスト内容のリストtxt_list
をExcelに書き出します。
ポイントを解説します。
txt_list
はリスト内リストになっているため、まず1ページ毎のリストのインデックスと内容をrowに格納します。
y=0 の時のrowは以下になります。
row = [1, ‘- 1 – 第 1 章 データサイエ…いるかを理解する。 ‘]
このリストをさらに次のfor文で処理していきます。
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ファイルの保存
1 2 3 | # 9:Excelファイルの保存 xlname = filename.split('.')[0] + '_excel.xlsx' wb.save(xlname) |
最後にExcelファイルを保存します。
PDFのファイル名「sample.pdf」から拡張子抜きの文字列を取得し、保存するファイル名をsample_excel.xlsxと設定します。filename.split('.')
で [‘sample’, ‘pdf’] のリストを取得し[0]
で1番目の要素を取り出しています。
・関連記事:文字列処理ー文字列の分割(split)
設定したファイル名でExcelファイルを保存します。
PythonでPDFのテキストを抽出する方法を解説しました。
・関連記事:PythonでPDFを読み込む(PyMuPDF, PyPDF2, PDFminer)
・関連記事:PythonでPDFファイルの画像を抽出する