請求書の金額を取り出したいときも、PDFに文字が入っているとは限りません。紙をスキャンした画像のPDFと、文字を持つPDFでは、必要な処理が違います。まず、手元の少数のファイルで、何が取り出せるかを確かめます。
文字抽出とOCRの違い
pypdfのextract_textは、PDFが持つテキストを取り出すための機能です。画像の中の文字を認識するOCRを行う機能ではありません。見た目では文字があっても、画像だけなら、この方法では文字を得られない場合があります。
選択してコピーできるかは最初の手がかりになりますが、正しい順序や値を取り出せる保証ではありません。利用してよい保存場所へコピーし、必要なページから試します。
ページごとに取り出す例
pypdfを利用できる環境で、input.pdfと同じフォルダーへ次のコードを保存します。出力はextracted.txtで、元のPDFへ書き込みません。
from pypdf import PdfReader
reader = PdfReader("input.pdf")
try:
if reader.is_encrypted:
raise ValueError("暗号化PDFは別途確認してください")
parts = []
empty_pages = []
for number, page in enumerate(reader.pages, start=1):
text = page.extract_text() or ""
if not text.strip():
empty_pages.append(number)
parts.append(f"=== page {number} ===\n{text}")
with open("extracted.txt", "x", encoding="utf-8") as out:
out.write("\n\n".join(parts))
print("ページ数:", len(reader.pages))
print("文字を得られなかったページ:", empty_pages)
finally:
reader.close()
Python 3.12.10・pypdf 6.13.1で、文字のある1ページと空白の1ページから成るテストPDFを読みました。文字の抽出と、2ページ目が空であることの記録を確認しています。実際の請求書やOCRの検証結果ではありません。
空の結果を、空の請求書と同じ意味にはしません。対象ページを開き、画像なのか、抽出しにくい構造なのかを確認します。暗号化された資料を扱う場合も、解除権限と業務上の方法を先に確認してください。
表と読み取り順の確認
PDFは見た目の位置を持つ形式で、表がそのままCSVの行列として保存されているとは限りません。二段組の文章、ヘッダー、脚注、金額の列が、期待する順で出ない場合があります。
抽出した文から金額だけを探す前に、項目名と値の対応、桁区切り、通貨、税込・税抜を、元ページと比べます。番号が出たからといって、同じ行の金額だと決めないようにします。
業務へ渡す前の区分
取り出せた、空だった、確認待ち、という状態を分けて残します。必要な項目が欠けた資料は、人が原本を確認するための一覧へ回します。読めなかった値を0に置き換えて、支払いなどの後続処理へ流しません。
OCRを使う場合も、認識した文字を正しい値として確定する前に照合が必要です。外部サービスへ資料を送るなら、個人情報や契約条件の確認も別に行います。
最初は数枚だけを使い、ページ数、必要な項目、誤りやすい文字を記録します。元PDFと抽出結果を対応させておくと、後で値を確かめ直せます。
関連する作業
PDFの結合・分割と、取り出した情報の扱いは次の記事でも確認できます。
