PythonでPDFから必要なテキスト情報を抽出する方法|pypdfの使い方
この記事では、Pythonを使ってPDFファイルから必要なテキストを抜き出す(抽出する)方法を解説します。PDFからテキストを抜き出すツールもありますが、Pythonを使うことで目的に合わせて取り出す情報を細かくカスタマイズすることが可能です。
はじめに
最近は、PDF形式のファイルを取り扱うことが多くなりました。これに伴い、「受け取ったPDFファイルから必要な部分を取り出したい」というニーズも増えているのではないかと思います。
私も、請求書や領収書などのPDFから日付や金額の情報を抜き出してエクセルで管理したり、報告書をテキスト化して修正したい場合などがあります。
PDFビューアを使えば、コピー&ペーストすることも可能ですが、手作業のコピペにはミスがつきものです。また、たくさんの請求書や領収書があると、1つ1つやるのも面倒です。
PDFから自動で情報を抜き出したくなります。PDFから情報を抜き出すための専用のツールもたくさんありますが、プログラミング言語を使って自作すれば、「自分のニーズにピッタリ」なツールを作ることができます。
プログラミング言語を使って処理する利点は、「任意の抽出・加工を行なって、任意のフォーマットで書き出すことができる」ことです
今回は、Pythonを使ってPDFファイルから必要な情報を抽出する方法を解説します。Pythonには、PDFを操作するためのライブラリが多数存在していますが、今回はその中からpypdfに絞って計説したいと思います。
以下では、pypdf
を使ってPDFファイルからテキストを抽出する基本的な手順から、より高度な使い方まで解説します。
pypdfの使い方(基本)
pypdfは、オープンソースのPython向けPDFライブラリです。
pypdf
を使うことで、PDFを読み書きすることが可能です。今回は、このpypdfを使って、テキストを抜き出す方法を紹介します。
pypdf
の他の機能については、以下のリンクを参考にしてください
github: https://github.com/py-pdf/pypdf
ドキュメント: https://pypdf.readthedocs.io/en/stable/
インストール
まずはpypdfをインストールしましょう。以下のコマンドを実行するだけで簡単にインストールできます。
pip install pypdf
インポート
以下のようにすることで、pypdfをインポートすることができます。
PdfReaderだけ使う場合
from pypdf import PdfReader
他の関数も使う場合
import pypdf
使い方
Readerオブジェクトを生成
PDFファイルを読み込むために、まずはReaderオブジェクトを生成します。以下のコードでは、sample.pdf
を読み込むためのreader
オブジェクトを生成しています。
reader = PdfReader("sample.pdf")
ページ数を確認する
読み込んだPDFファイルのページ数を確認するには、len(reader.pages)
を使用します。
num_pages = len(reader.pages)
print(f"ページ数: {num_pages}")
指定したページのテキストを取り出す
特定のページのテキストを抽出するには、pages[xx]
としてページにアクセスし、extract_text()
でテキストを抽出します。
page = reader.pages[0] # 1ページ目を指定
text = page.extract_text()
print(text)
高度な使い方
暗号化されたPDFを読み込む
暗号化されたPDFファイルを読み込む場合は、以下のようにパスワードを指定します。プログラム中のpassword
の部分には、PDFに設定されているパスワード🔑を指定します。
reader = PdfReader("encrypted.pdf")
reader.decrypt("password")
pypdfを使い方(応用例)
複数ファイルを処理する
複数のPDFファイルを処理する場合のコード例です。pdf_files
に含まれているファイルを全て読み込んで、テキストをall_texts
に格納します。
プログラム的には、for
文でファイルの読み込み、各ページに対するテキストの抽出を繰り返しています。
import os
from pypdf import PdfReader
pdf_files = ["file1.pdf", "file2.pdf", "file3.pdf"]
all_texts = []
for file in pdf_files:
reader = PdfReader(file)
for page in reader.pages:
all_texts.append(page.extract_text())
特定の行を抜き出す
特定の行を抽出するには、抽出したテキストを行ごとに分割して処理します。下記の例では、特定のキーワードに一致する行だけ抜き出して表示されます。特定のキーワードには、好きなキーワードを設定します。
page = reader.pages[0]
text = page.extract_text()
lines = text.split("\n")
for line in lines:
if "特定のキーワード" in line:
print(line)
文字数をカウントする
抽出したテキストの文字数をカウントするコード例です。
なお、改行コードなども1文字とカウントされてしまうので必要であれば除外しておきます。
text = page.extract_text()
char_count = len(text)
print(f"文字数: {char_count}")
pypdfを使った実例
amazonのinvoiceから登録番号と合計金額を抜き出す処理
Amazonでは、注文ページから適格請求書のPDFファイルをダウンロードすることができます。ここでは、このPDFファイルから登録番号と合計価格を抜き出してみます。
下記のコードでは、Amazonの注文ページからダウンロードできる適格請求書から、登録番号(Tからはじまる番号)と合計価格を抜き出してCSVファイル(output.csv
)に保存します。このプログラムは、必要経費の処理に必要な情報を抜き出すために作成しました。なお、少し修正すれば、税抜き、税額なども同じ要領抜き出すことも可能です。
処理した結果はCSV形式なので、エクセルや他の表計算ソフトにコピー&ペースト可能です。このように自動化すれば、金額などの写し間違えをなくすことができます。
PDFの構造がファイルごとに異なるので、それぞれのファイル形式に合わせて抜き出し部分を修正する必要があります
ただ、同じ形式であれば同じ方法で抜き出せるので、一気に抜き出して保存することで事務処理を軽減できます。
import pypdf
import pandas as pd
from tqdm import tqdm
import glob
pdf_files = glob.glob("*Amazon_invoice.pdf")
F = []
T = []
P = []
for pdf_file in tqdm(pdf_files):
reader = pypdf.PdfReader(pdf_file)
F.append(pdf_file)
T.append("")
P.append("")
for e in tqdm(reader.pages):
txt = e.extract_text()
for v in txt.split("\n"):
if "登録番号" in v :
v = v.split()[-1]
T[-1] = v
if "合計" in v :
v = v.split()
if len(v) > 3:
v = v[3].replace("合計", "")
P[-1] = v[1:]
df = pd.DataFrame()
df["請求書ファイル名"]=F
df["登録番号"]=T
df["合計金額"]=P
# print(T, P)
df.to_csv("output.csv", index=False)
print(df)
まとめ
pypdfを使うことで、PDFファイルから簡単にテキストを抽出し、さらに様々な処理を施すことができます。本記事で紹介した基本的な使い方や高度なテクニックを活用して、効率的にPDFファイルを扱いましょう。