Python PDF automation dashboard

請求書、見積書、領収書、申込書、検査票などのPDF帳票を開き、金額や日付を探してExcelへ転記していませんか。

この作業は「慣れれば早い」と思われがちですが、件数が増えるほど次の問題が出ます。

  • 入力ミスが起きる
  • ファイル名を取り違える
  • 確認漏れが発生する
  • 担当者しか処理できない
  • 毎月同じ作業に時間を取られる

PDF帳票処理は、Pythonで自動化しやすい業務の一つです。ただし、いきなりコードを書き始めると失敗します。重要なのは、PDFの種類を見分け、抽出項目を絞り、検証ルールとログまで含めて設計することです。

この記事では、初心者向けに PythonでPDF帳票から必要情報を抽出する基本設計 を、手順・失敗対策・KPIまで含めて解説します。

この記事で分かること

  • PythonでPDF帳票を自動抽出する全体像
  • pdfplumberを使うべきPDFと、OCRが必要なPDFの見分け方
  • 請求番号、金額、日付を抽出する基本コード
  • 抽出ミスを防ぐ検証ルール
  • CSVやスプレッドシートへ出力する流れ
  • 運用時に見るべきKPI
  • 自動化してよい帳票、慎重に扱うべき帳票の判断基準

実行ログ:Hiro環境での最小検証

この記事では一般論だけでなく、Hiroのローカル環境で実行した最小検証ログを前提にします。

hiro_pdf_extract_smoke_test
date=2026-07-12 timezone=Asia/Tokyo
engine=python 3.11.9 pdfplumber
samples=3 elapsed_ms=8.6
texts=
- Invoice No: A-001 Amount: 12800 Due: 2026-07-31
- Invoice No: A-002 Amount: 9800 Due: 2026-08-15
- Invoice No: A-003 Amount: 45000 Due: 2026-08-31

検証内容は、メモリ上で作成した最小構成のPDFを3件読み込み、pdfplumberでテキスト抽出したものです。

注意点があります。このログは、実務帳票の処理速度や精度を保証するものではありません。実務のPDFには、罫線、複数ページ、縦書き、画像スキャン、文字化け、表の崩れ、発行元ごとのレイアウト差があります。

ただし、次の判断材料にはなります。

  • テキスト情報を持つPDFなら、Pythonで抽出できる可能性が高い
  • 最初の検証は小さく始められる
  • 本番化する前に、成功数・失敗数・確認待ち件数をログ化すべき

PDF情報抽出の全体像

PythonでPDF帳票から情報を抽出する流れは、次の4段階です。

PDF extraction flow diagram

  1. 読む
    PDFをPythonで開き、文字や表を取り出します。

  2. 探す
    抽出したテキストから、請求番号、金額、日付などを見つけます。

  3. 整える
    金額のカンマを外す、日付形式をそろえる、空欄をエラーにするなどの処理を行います。

  4. 流す
    CSV、Excel、Googleスプレッドシート、会計ソフト、通知ツールなどへ渡します。

ここまで作ると、人間の役割は「全件転記」ではなく「例外確認」に変わります。これがPDF帳票自動化の大きな価値です。

ステップ1:対象PDFの種類を判定する

最初に、PDFがどの種類かを確認します。

種類特徴主な対応
テキストPDF文字を選択・コピーできるpdfplumberなどで抽出
画像PDFスキャン画像だけで文字選択できないOCRが必要
混在PDF一部は文字、一部は画像テキスト抽出とOCRを併用

確認方法は簡単です。PDFビューアで金額や日付をドラッグし、コピーできるか試します。

コピーできるなら、テキストPDFの可能性が高いです。コピーできないなら、OCRが必要になる可能性があります。OCRとは、画像内の文字を読み取る技術です。たとえば、スキャンされた領収書画像から「税込 12,800円」を読み取る処理です。

ここを確認せずに進めると、「コードは正しいのに何も抽出できない」という失敗が起きます。

ステップ2:抽出項目を決める

初心者が失敗しやすいのは、「PDFの中身を全部取りたい」と考えることです。

最初は、業務に必要な項目だけに絞ります。

項目必須かエラー時の扱い
請求番号A-001必須処理停止
請求日2026-07-12必須要確認リストへ
支払期限2026-07-31任意空欄許可
金額12800必須処理停止
取引先名ABC株式会社任意空欄許可

設計のポイントは、必須項目と任意項目を分けることです。

必須項目が欠けたPDFは自動処理せず、確認待ちに回します。任意項目は空欄を許可します。この切り分けがあると、1件の例外で全体の処理が止まることを防げます。

ステップ3:PDFからテキストを取り出す

テキストPDFなら、まずpdfplumberで抽出を試します。

import pdfplumber

pdf_path = "invoice.pdf"

with pdfplumber.open(pdf_path) as pdf:
    text = "\n".join(page.extract_text() or "" for page in pdf.pages)

print(text)

この段階では、まだデータを整えません。まずは生の抽出結果を見ます。

確認するポイントは次の通りです。

  • 請求番号が取れているか
  • 金額が取れているか
  • 日付が取れているか
  • 表の列順が崩れていないか
  • 改行位置が不自然ではないか
  • 全角スペースや余計な記号が混ざっていないか

抽出結果はファイルに保存しておくと、後で正規表現を調整しやすくなります。

from pathlib import Path

Path("debug_extracted_text.txt").write_text(text, encoding="utf-8")

ステップ4:正規表現で必要項目を抜き出す

正規表現とは、文字のパターンを指定して検索する方法です。

たとえば、次の文字列から請求番号、金額、支払期限を取り出します。

Invoice No: A-001 Amount: 12800 Due: 2026-07-31

基本コードは次の通りです。

import re

text = "Invoice No: A-001 Amount: 12800 Due: 2026-07-31"

invoice_no = re.search(r"Invoice No:\s*(\S+)", text)
amount = re.search(r"Amount:\s*([0-9,]+)", text)
due = re.search(r"Due:\s*([0-9]{4}-[0-9]{2}-[0-9]{2})", text)

row = {
    "invoice_no": invoice_no.group(1) if invoice_no else None,
    "amount": int(amount.group(1).replace(",", "")) if amount else None,
    "due": due.group(1) if due else None,
}

print(row)

日本語帳票では、表記ゆれを想定します。

amount = re.search(r"請求金額[::]?\s*([0-9,]+)\s*円?", text)
date = re.search(
    r"請求日[::]?\s*([0-9]{4})年([0-9]{1,2})月([0-9]{1,2})日",
    text,
)

正規表現は、1本で全部取ろうとしない方が安全です。請求番号、金額、日付、取引先名を別々に抽出し、それぞれ検証します。

ステップ5:抽出結果を検証する

PDF抽出で最も重要なのは、抽出後の検証です。

「文字が取れた」だけでは不十分です。間違った金額や日付をそのままCSVに流すと、手作業より危険になります。

検証ルールの例です。

項目検証ルール異常時の扱い
請求番号空欄ではない、過去データと重複しない確認待ち
金額0円より大きい、上限額を超えない処理停止または確認待ち
日付想定期間内にある確認待ち
明細合計合計金額と一致する確認待ち
取引先名登録済み取引先と一致する確認待ち

簡単な検証コードは次のように書けます。

def validate_row(row):
    errors = []

    if not row.get("invoice_no"):
        errors.append("invoice_no is missing")

    if row.get("amount") is None:
        errors.append("amount is missing")
    elif row["amount"] <= 0:
        errors.append("amount must be greater than 0")

    if not row.get("due"):
        errors.append("due date is missing")

    return errors

検証結果によって、処理先を分けます。

success/
needs_review/
failed/

この分類にすると、人間は全PDFを確認する必要がありません。確認すべきPDFだけに集中できます。

ステップ6:CSVに出力する

最初の出力先はCSVがおすすめです。Excel、Googleスプレッドシート、BIツール、会計ソフト連携の入口にしやすいからです。

import csv

rows = [
    {"invoice_no": "A-001", "amount": 12800, "due": "2026-07-31"},
    {"invoice_no": "A-002", "amount": 9800, "due": "2026-08-15"},
]

with open("extracted_invoices.csv", "w", newline="", encoding="utf-8-sig") as f:
    writer = csv.DictWriter(f, fieldnames=["invoice_no", "amount", "due"])
    writer.writeheader()
    writer.writerows(rows)

encoding="utf-8-sig"にしておくと、Excelで開いたときに文字化けしにくくなります。

出力ファイルには、抽出結果だけでなく、元PDFのファイル名も入れると後から確認しやすくなります。

source_file,invoice_no,amount,due,status
invoice_A001.pdf,A-001,12800,2026-07-31,success

ステップ7:ログを残す

定期運用するなら、ログは必須です。

ログがないと、次のことが分かりません。

  • 何件処理したか
  • 何件成功したか
  • 何件確認待ちになったか
  • どのPDFで失敗したか
  • 前回より改善したか

最低限、次の形式で残します。

run_date=2026-07-12
input_files=42
success=39
needs_review=3
failed=0
output=extracted_invoices.csv

実務ではJSON形式にすると、後から集計しやすくなります。

{
  "run_date": "2026-07-12",
  "input_files": 42,
  "success": 39,
  "needs_review": 3,
  "failed": 0,
  "output": "extracted_invoices.csv"
}

ログは「動いた証拠」ではなく、改善の材料です。確認待ちが多い帳票を見れば、正規表現を直すべきか、OCRを入れるべきか、帳票フォーマットを変えるべきか判断できます。

ステップ8:定期実行する

手作業でPythonを実行するだけでは、自動化の効果は限定的です。定期実行まで設計します。

代表的な方法は次の通りです。

実行環境方法
Windowsタスクスケジューラ
Linuxサーバーcron
GitHubGitHub Actionsのスケジュール実行
クラウドCloud Run、Cloud Functionsなど

初心者は、まずローカルPCの決まったフォルダで試すのが現実的です。

例です。

input/
  invoice_A001.pdf
  invoice_A002.pdf

output/
  extracted_invoices.csv

logs/
  run_2026-07-12.json

needs_review/
  invoice_error_001.pdf

このようにフォルダを分けると、処理済み、確認待ち、失敗が見分けやすくなります。

専門家目線のチェックポイント

帳票フォーマットは本当に固定か

同じ会社の請求書でも、部署、発行システム、月、ページ数によってレイアウトが変わることがあります。

最低でも、次のパターンを集めて確認します。

  • 金額の桁数が違うPDF
  • 明細行が1行のPDF
  • 明細行が複数行のPDF
  • 2ページ以上のPDF
  • 取引先名が長いPDF
  • 消費税や割引が含まれるPDF

Hiro環境の検証は3件の最小PDFでした。これは動作確認としては十分ですが、本番判断には足りません。実務では、10件から30件程度のサンプルを集め、抽出成功率と要確認率を測る方が安全です。

OCR前提の帳票は誤認識を見込む

画像PDFではOCRが必要です。ただし、OCRは必ず誤認識します。

よくある誤認識は次の通りです。

  • 1I
  • 0O
  • 8B
  • の欠落
  • 桁区切りカンマの欠落
  • 日付の区切り文字の読み違い

金額、契約番号、請求番号のように誤りの影響が大きい項目は、OCR結果をそのまま使わず、検証ルールを必ず入れます。

最初から完全自動化を狙うより、次の順序が堅実です。

  1. 全件を人間確認する
  2. 抽出結果と人間確認結果を比較する
  3. 誤抽出パターンを記録する
  4. 異常値だけ確認する運用に変える
  5. 一定期間問題がなければ自動承認範囲を広げる

後続アクションまで設計する

PDF抽出そのものはゴールではありません。抽出したデータを何に使うかが重要です。

例です。

PDF抽出項目後続アクション
請求書PDF請求番号、金額、支払期限入金予定表、未回収アラート
仕入れ明細PDF商品名、単価、数量単価差異検出
広告レポートPDF費用、CV数、CPA停止候補広告の抽出
ポイント明細PDF利用額、付与ポイント還元率集計

収益やポイントの改善を狙う場合も、利益を保証するものではありません。価値があるのは、人間が毎回PDFを開いて判断する状態から、機械が候補を出す状態へ変えられることです。

画像で説明すべき処理フロー

PDF抽出の記事では、処理フローを画像で示すと理解しやすくなります。

含める要素は次の通りです。

  • 左:請求書PDF、領収書PDF、レポートPDF
  • 中央:Python処理、テキスト抽出、正規表現、検証
  • 右:CSV、Googleスプレッドシート、通知、会計ソフト
  • 下部:ログ、エラーリスト、人間確認キュー

PDF to spreadsheet automation pipeline

説得力を上げるなら、次の3点を並べるとよいです。

  • 抽出前のPDF
  • 抽出後のCSV
  • 実行ログ

特に、成功数、確認待ち数、失敗数が見えるログは重要です。単なるAI風の説明ではなく、実際に運用できる仕組みとして伝わります。

よくある失敗と対策

失敗1:PDFなら全部同じ方法で読めると思う

テキストPDFと画像PDFでは処理方法が違います。画像PDFにpdfplumberを使っても、文字が取れないことがあります。

対策は、最初に文字選択できるか確認することです。文字選択できない場合は、OCR前提で設計します。

失敗2:抽出項目を増やしすぎる

最初から全項目を抽出しようとすると、設計が複雑になります。

対策は、業務上必要な項目から始めることです。請求番号、金額、日付のように、後続処理に必要な項目を優先します。

失敗3:正規表現を複雑にしすぎる

1本の巨大な正規表現で全部取ろうとすると、修正が難しくなります。

対策は、項目ごとに小さく分けることです。抽出できなかった項目だけを個別に調整できるようにします。

失敗4:例外処理がない

1件の形式違いで全体が止まる設計は危険です。

対策は、成功、確認待ち、失敗を分けることです。確認待ちだけを人間が見ればよい状態にします。

失敗5:ログを残していない

ログがないと、どのPDFで失敗したのか、改善したのかが分かりません。

対策は、毎回の処理件数、成功件数、確認待ち件数、失敗件数、出力先を記録することです。

失敗6:完全自動化を急ぎすぎる

帳票の品質が安定していない段階で完全自動化すると、誤抽出に気づけません。

対策は、段階的に自動化率を上げることです。

  1. 抽出だけ自動化する
  2. 全件を人間確認する
  3. 異常値だけ人間確認する
  4. 一定期間のログを見て自動承認範囲を広げる
  5. 例外だけ通知する

成果を測るKPI

PDF抽出の改善は、感覚ではなくKPIで測ります。

KPI見る理由
抽出成功率自動処理できた割合を見る100件中92件成功
要確認率人間作業の残量を見る100件中8件確認
誤抽出件数自動化の危険度を見る金額誤り1件
1件あたり処理時間時間削減効果を見る手作業3分、Python処理数秒
再実行回数運用の安定度を見る月3回再実行
修正にかかった時間保守コストを見る月30分
後続アクション検知件数業務効果を見る未回収候補2件、単価差異5件

数字を書くときは、必ず前提条件を添えます。

悪い例です。

抽出成功率92%

良い例です。

2026年7月の請求書PDF100件を対象に、請求番号・金額・支払期限の3項目を抽出した結果、92件が自動処理成功、8件が確認待ち。

前提がある数字は、改善にも比較にも使えます。

使えないケースと限界

PythonによるPDF情報抽出は強力ですが、万能ではありません。

次のケースでは慎重に設計します。

  • 手書き文字が多い帳票
  • 解像度が低いスキャンPDF
  • レイアウトが毎回変わるPDF
  • 縦書きや複雑な表が多いPDF
  • 法務、税務、医療など高リスク領域の帳票
  • 発行元システムの変更でレイアウトが変わる帳票

特に、金額や契約内容に関わる帳票では、監視なしの完全自動化は危険です。

現実的な運用は、次の形です。

  • 正常値は自動処理する
  • 異常値は確認待ちにする
  • 失敗したPDFはログに残す
  • 定期的にサンプル検査する
  • フォーマット変更があったら抽出ルールを見直す

反論:手作業の方が早いのでは?

少量のPDFなら、手作業の方が早い場合があります。

たとえば、月に3件だけの請求書なら、Python自動化に時間をかける必要はないかもしれません。

自動化を検討すべき目安は次の通りです。

  • 毎月同じ種類のPDFが10件以上ある
  • 転記ミスが起きると影響が大きい
  • 確認項目が毎回同じ
  • 担当者以外でも処理できるようにしたい
  • 後続の集計や通知まで自動化したい

逆に、帳票形式が毎回違い、件数も少なく、後続処理もないなら、無理に自動化しない判断も正しいです。

読了後すぐに取れるアクション

今日やることは、コードを書くことではありません。まず対象PDFを5件集めて、次の表を埋めます。

チェック項目記入例
PDFの種類テキストPDF / 画像PDF / 混在PDF
抽出したい項目請求番号、金額、支払期限
必須項目請求番号、金額
任意項目取引先名、備考
例外条件金額空欄、日付なし、重複番号
出力先CSV、Googleスプレッドシート
後続アクション未回収通知、利益率チェック
確認担当経理担当、運用担当
成功基準抽出成功率90%以上、誤抽出0件

この表が埋まれば、設計の半分は終わっています。逆に、この表が曖昧なままコードを書き始めると、途中で作り直しになりやすいです。

まとめ:PDF抽出は「転記の自動化」ではなく「例外だけを見る仕組み」

PythonでPDF帳票から情報抽出する基本設計は、次の流れです。

  1. PDFの種類を判定する
  2. 抽出項目を決める
  3. Pythonでテキストを取り出す
  4. 正規表現や表抽出で必要情報を抜く
  5. 必須項目と異常値を検証する
  6. CSVやスプレッドシートへ出力する
  7. ログを残す
  8. 定期実行する
  9. KPIを見て改善する
  10. 後続アクションへ接続する

PDF抽出の目的は、単にCSVを作ることではありません。毎月発生する帳票処理を、人間が全件見る状態から、機械が大半を処理し、人間は例外だけを見る状態へ変えることです。

そのためには、コードだけでなく、検証ルール、ログ、確認待ちフロー、KPIまで含めて設計する必要があります。

まずは5件のPDFで小さく試し、抽出結果とログを見ながら改善してください。そこから、定期実行、通知、スプレッドシート連携へ広げるのが、失敗しにくい進め方です。


本気で自動化・不労所得を構築したい方向けの実践マニュアル

PDF帳票の情報抽出は、自動化資産づくりの入口です。

本当に狙うべきは、データ収集、判定、通知、実行、記録までが人間の手を離れて回り続ける仕組みです。

「毎日PDFを開く」「毎月Excelに転記する」「利益が出そうな情報を目視で探す」

この繰り返しから抜け出したい方は、次に実践マニュアルで具体的な型を確認してください。

👉 本気で自動化・不労所得を構築したい方向けの実践マニュアルを見る