スクレイピングは「動いているように見えて、実はデータが壊れている」状態が起きやすい仕組みです。HTTPは200でも中身がエラーページ、DOMが変わって空配列、ブロックで遅延増大など、失敗が多層に潜みます。この記事では、失敗を早く・正しく検知し、復旧を自動化して、最後に運用負荷を下げるための監視設計を手順としてまとめます。 スクレイピング運用の監視は、次の4レイヤで設計すると抜け漏れが減ります。 押さえたい原則:「エラー通知」だけでは不十分です。 復旧を速くするには、まず失敗を「原因別」に分類し、検知指標と復旧手段を紐づけます。代表例は次の通りです。 注意:「HTTP 200=成功」ではありません。ログイン要求ページやBot対策ページが200で返るケースがあるため、本文のシグネチャ(タイトル、特定文言、フォーム有無)で検知する仕組みを入れてください。 監視は「稼働」「性能」「品質」「コスト」の4系統に分けると運用しやすくなります。 ここからが本題です。検知は「ログ → メトリクス → アラート」の順で組むと、後から条件変更が容易です。 最低限、次のフィールドを必ず出します(JSONログ推奨)。 Prometheus等を使う場合、次のようなカウンタ/ヒストグラムが扱いやすい設計です。
監視設計の全体像
“成功したはずなのに値がない/おかしい”を検知するために、データ品質の監視(件数、必須項目の欠損率、分布の急変)を必ず入れてください。失敗パターンを分類
分類
典型症状
検知の要点
主な復旧
ネットワーク
DNS失敗、接続タイムアウト
例外種別、タイムアウト率
再試行、プロキシ切替
ブロック/レート
429/403、CAPTCHA
ステータス比率、遅延増大、本文特徴
バックオフ、同時実行制御
DOM変更
抽出0件、必須項目null
件数・欠損率、セレクタ失敗
パーサ更新、フォールバック
サイト側障害
5xx増加、応答遅延
5xx率、RTのP95
リトライ、待機、後追い回収
下流障害
DB書込失敗、キュー詰まり
永続化失敗率、キュー滞留
DLQ隔離、再投入
監視すべき指標
稼働を測る
性能を測る
品質を測る
コストを測る
検知の実装手順
ログを構造化
メトリクスに落とす
scrape_job_runs_total{job="price",result="success"}
scrape_job_runs_total{job="price",result="fail"}
scrape_http_requests_total{job="price",status="429"}
scrape_parse_items_total{job="price"}
scrape_parse_missing_required_total{job="price"}
scrape_request_duration_seconds_bucket{job="price",le="..."}アラートは「即時対応」と「営業時間対応」に分け、閾値と継続時間(for)を変えます。例: 運用のコツ:「リトライ中に通知が鳴り続ける」設計は疲弊します。 スクレイピングは「結果が出るべき時刻に出ていない」を検知できると強いです。実行基盤によってアプローチが変わるため、ここでは3つの方式を紹介します。 ジョブ完了時に外部へpingし、未到達で失敗とみなす方式です。Healthchecks.ioは「ジョブが期待時刻に走らない」「異常に長い実行」なども検知できる、と公式ドキュメントで説明されています。 アラート条件を決める
まずは“復旧できない失敗”だけを強く鳴らし、軽微な揺らぎは集計(ダッシュボード)で見る設計に寄せるのがおすすめです。死活監視の作り方
ハートビート方式
オーケストレータのデッドライン監視
Airflow・Dagster・Prefectなどのオーケストレータを使っている場合、ジョブの完了期限を設定し、超過時に通知する仕組みが組み込みで使えることが多いです。
注意:AirflowのSLAは「タスク開始からの経過」ではなく、実行日(DAG Runの基準時刻)に対して評価される点に癖があります。SLA導入時は、この仕様を前提に期待時間を設計してください。
カナリアチェック
本番ジョブとは別に、少数の代表URLを定期的に取得し、応答ステータス・本文シグネャ・主要セレクタの存在を確認する軽量チェックです。DOM変更やブロック強化を本番ジョブの失敗より先に検知でき、パーサ更新やアクセス戦略の見直しを先手で回せます。
復旧フローの設計
復旧は「原因切り分け → 自動復旧 → 手動復旧」の順に、レベルを分けて運用します。
切り分けの手順
- 失敗phase(fetch/parse/store)を確認
- HTTPステータス(429/403/5xx)とレイテンシを見る
- 本文シグネチャ(ブロックページか)を確認
- 抽出件数・欠損率の変化を見る(DOM変更か)
- 下流(DB/キュー)メトリクスを見る
自動復旧の基本
現場で効きやすいのは、次の3点セットです。
- 再試行:短期のネットワーク揺らぎを吸収
- バックオフ:429/ブロック兆候で待つ
- 隔離:壊れた入力をDLQに逃がし全体停止を防ぐ
429時の扱い
レート制限系は、相手が「いつ再試行できるか」を返す場合があります。例えばCloudflareのAPIでは、レート制限時に retry-after ヘッダが返り、何秒待てばよいかを示すと記載されています。スクレイピング対象が同様のヘッダを返すなら、それを最優先で尊重するのが安全です。
import random
import time
MAX_RETRIES = 5
BASE = 1.0
CAP = 60.0
def backoff_sleep(attempt: int, retry_after: float | None = None) -> None:
# retry-afterがある場合は優先
if retry_after is not None:
time.sleep(retry_after)
return
# exponential backoff + jitter
exp = min(CAP, BASE * (2 ** attempt))
jitter = random.uniform(0, exp * 0.2)
time.sleep(exp + jitter)
設計ポイント:バックオフは「対象サイト単位」で効かせてください。URL単位で待つと、同一ドメインへ別ジョブが攻撃的にアクセスし続ける事故が起きます。 失敗した分だけを確実に取り戻すには、「再実行の単位」と「冪等性」が鍵です。 同じ入力を複数回処理しても結果が壊れないよう、保存時に一意キー(site_id+item_id+timestampなど)を設計します。更新系はUPSERT、履歴系は重複排除(unique制約)を基本にすると運用が安定します。 注意:「失敗したら全再実行」は最終手段です。アクセス急増でブロックを誘発し、二次障害になりやすいため、まずは差分再収集(失敗分だけ)を前提にしてください。 監視が鳴っても、手順書がないと復旧は遅れます。オンコール/当番が迷わない最小構成のテンプレートを示します。 最後に、監視設計を“回る形”にするための定番をまとめます。 重大障害は即時(PagerDuty等)、品質劣化はSlack/メールのように分離し、ノイズを減らします。ハートビート監視サービスは通知チャネルを複数持てる旨が公式に説明されており、冗長化にも有効です。 再実行と再収集
再実行単位を決める
冪等性を確保
障害対応の手順書
一次対応
原因別の対応
復旧確認
運用を軽くする工夫
アラートに文脈を載せる
通知先を分ける
監視の信頼性も監視
監視送信自体が失敗すると誤検知が増えます。Healthchecks.ioはping送信にタイムアウトやリトライを設定して堅牢性を上げる例(curlの--max-timeや--retry)を示しています。監視のための通信が、処理本体をブロックしない設計にしてください。
よくある失敗
- ログが足りず切り分け不能:phaseとエラー分類がない
- データ品質の監視がない:成功率だけ見て“空データ”を見逃す
- リトライ無限:429に対して攻撃的になり、ブロックを悪化させる
- 再実行が全量:二次障害(アクセス急増)を誘発する
- 通知が多すぎる:軽微な揺らぎまで即時通知して疲弊する
監視設計を改善しませんか?
失敗検知から復旧までを運用に落とし込むには、指標設計と復旧手順の整備が重要です。現状の構成に合わせた監視・アラート設計の壁打ちも可能です。
まとめ
スクレイピング運用の監視設計は、稼働監視だけでなくデータ品質監視まで含めて初めて機能します。失敗パターンを分類し、ログ→メトリクス→アラートの順で設計し、再試行・バックオフ・隔離(DLQ)・差分再収集を組み合わせて復旧までを手順化してください。これにより「気づけない失敗」と「復旧が遅い運用」を同時に減らせます。