自動化スクレイピング

スクレイピング運用の監視設計:失敗検知〜復旧までの実践手順

スクレイピング運用で起きがちな失敗(429/403、DOM変更、0件、保存失敗)を分類し、ログ設計・指標・アラート条件から、再試行/バックオフ/DLQ隔離/差分再収集で復旧する実践手順を解説します。

Ibuki Yamamoto
Ibuki Yamamoto
2026年2月10日 14分で読めます

スクレイピングは「動いているように見えて、実はデータが壊れている」状態が起きやすい仕組みです。HTTPは200でも中身がエラーページ、DOMが変わって空配列、ブロックで遅延増大など、失敗が多層に潜みます。この記事では、失敗を早く・正しく検知し、復旧を自動化して、最後に運用負荷を下げるための監視設計を手順としてまとめます。

この記事でわかること
  • スクレイピングで監視すべき失敗パターンと指標
  • 検知→切り分け→復旧までの運用フロー設計
  • 再試行・隔離・再実行を組み合わせた復旧手順

監視設計の全体像

スクレイピング運用の監視は、次の4レイヤで設計すると抜け漏れが減ります。

  1. スケジューラ層:ジョブが「実行されたか」「遅延していないか」
  2. 収集層:HTTP・DNS・TLS・タイムアウト・ブロックなどの「取得成功率」
  3. 解析層:DOM変更・抽出ロジック不整合などの「データ妥当性」
  4. 出力層:保存・配信・ETLの「書き込み成功率」

押さえたい原則:「エラー通知」だけでは不十分です。
“成功したはずなのに値がない/おかしい”を検知するために、データ品質の監視(件数、必須項目の欠損率、分布の急変)を必ず入れてください。

失敗パターンを分類

復旧を速くするには、まず失敗を「原因別」に分類し、検知指標と復旧手段を紐づけます。代表例は次の通りです。

分類 典型症状 検知の要点 主な復旧
ネットワーク DNS失敗、接続タイムアウト 例外種別、タイムアウト率 再試行、プロキシ切替
ブロック/レート 429/403、CAPTCHA ステータス比率、遅延増大、本文特徴 バックオフ、同時実行制御
DOM変更 抽出0件、必須項目null 件数・欠損率、セレクタ失敗 パーサ更新、フォールバック
サイト側障害 5xx増加、応答遅延 5xx率、RTのP95 リトライ、待機、後追い回収
下流障害 DB書込失敗、キュー詰まり 永続化失敗率、キュー滞留 DLQ隔離、再投入

注意:「HTTP 200=成功」ではありません。ログイン要求ページやBot対策ページが200で返るケースがあるため、本文のシグネチャ(タイトル、特定文言、フォーム有無)で検知する仕組みを入れてください。

監視すべき指標

監視は「稼働」「性能」「品質」「コスト」の4系統に分けると運用しやすくなります。

稼働を測る

  • ジョブ実行回数(スケジュール通りか)
  • 成功/失敗/リトライ回数
  • 最終成功時刻(死活監視に近い)

性能を測る

  • リクエストレイテンシ(平均/中央値/P95)
  • タイムアウト率
  • 同時実行数、キュー滞留時間

品質を測る

  • 抽出件数(0件の急増)
  • 必須フィールド欠損率(価格、在庫、SKUなど)
  • 分布変化(価格の中央値が突然0/極端値になる等)

コストを測る

  • 1ジョブあたりのリクエスト数
  • プロキシ費用の増大兆候(リトライ増)
  • ヘッドレスブラウザ稼働時間

検知の実装手順

ここからが本題です。検知は「ログ → メトリクス → アラート」の順で組むと、後から条件変更が容易です。

ログを構造化

最低限、次のフィールドを必ず出します(JSONログ推奨)。

  • job_name / run_id / target(URLやサイトID)
  • phase(fetch/parse/storeなど)
  • status(success/fail/retry)
  • http_status / error_type / elapsed_ms
  • items_count / missing_required_count

メトリクスに落とす

Prometheus等を使う場合、次のようなカウンタ/ヒストグラムが扱いやすい設計です。

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)を変えます。例:

  • 即時:最終成功からX分以上、5xxが急増、保存層が停止
  • 営業時間:品質劣化(欠損率上昇、抽出0件増)

運用のコツ:「リトライ中に通知が鳴り続ける」設計は疲弊します。
まずは“復旧できない失敗”だけを強く鳴らし、軽微な揺らぎは集計(ダッシュボード)で見る設計に寄せるのがおすすめです。

死活監視の作り方

スクレイピングは「結果が出るべき時刻に出ていない」を検知できると強いです。実行基盤によってアプローチが変わるため、ここでは3つの方式を紹介します。

ハートビート方式

ジョブ完了時に外部へpingし、未到達で失敗とみなす方式です。Healthchecks.ioは「ジョブが期待時刻に走らない」「異常に長い実行」なども検知できる、と公式ドキュメントで説明されています。

オーケストレータのデッドライン監視

Airflow・Dagster・Prefectなどのオーケストレータを使っている場合、ジョブの完了期限を設定し、超過時に通知する仕組みが組み込みで使えることが多いです。

注意:AirflowのSLAは「タスク開始からの経過」ではなく、実行日(DAG Runの基準時刻)に対して評価される点に癖があります。SLA導入時は、この仕様を前提に期待時間を設計してください。

カナリアチェック

本番ジョブとは別に、少数の代表URLを定期的に取得し、応答ステータス・本文シグネャ・主要セレクタの存在を確認する軽量チェックです。DOM変更やブロック強化を本番ジョブの失敗より先に検知でき、パーサ更新やアクセス戦略の見直しを先手で回せます。

復旧フローの設計

復旧は「原因切り分け → 自動復旧 → 手動復旧」の順に、レベルを分けて運用します。

切り分けの手順

  1. 失敗phase(fetch/parse/store)を確認
  2. HTTPステータス(429/403/5xx)とレイテンシを見る
  3. 本文シグネチャ(ブロックページか)を確認
  4. 抽出件数・欠損率の変化を見る(DOM変更か)
  5. 下流(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単位で待つと、同一ドメインへ別ジョブが攻撃的にアクセスし続ける事故が起きます。

再実行と再収集

失敗した分だけを確実に取り戻すには、「再実行の単位」と「冪等性」が鍵です。

再実行単位を決める

  • URL単位:粒度が細いが管理が増える
  • ページ種別単位:カテゴリページ、商品ページなど
  • 時間窓単位:1時間分、1日分の取りこぼしを再収集

冪等性を確保

同じ入力を複数回処理しても結果が壊れないよう、保存時に一意キー(site_id+item_id+timestampなど)を設計します。更新系はUPSERT、履歴系は重複排除(unique制約)を基本にすると運用が安定します。

注意:「失敗したら全再実行」は最終手段です。アクセス急増でブロックを誘発し、二次障害になりやすいため、まずは差分再収集(失敗分だけ)を前提にしてください。

障害対応の手順書

監視が鳴っても、手順書がないと復旧は遅れます。オンコール/当番が迷わない最小構成のテンプレートを示します。

一次対応

  1. 影響範囲:どのサイト/ジョブ/データが対象か
  2. 現象:失敗phase、エラー種別、発生開始時刻
  3. 暫定対処:停止/間引き/バックオフ強化

原因別の対応

  • 429/403:同時実行を下げる、レート制限に合わせる、ヘッダ/UA/セッション再取得
  • DOM変更:抽出0件/欠損率を根拠にパーサ更新、フォールバック(別セレクタ/JSON-LD)
  • 5xx:時間を置いて再収集、取りこぼし窓を再実行
  • 保存失敗:DLQ隔離、DB復旧後に再投入

復旧確認

  • 最終成功時刻が更新された
  • 件数・欠損率が通常レンジに戻った
  • リトライ率が平常に戻った

運用を軽くする工夫

最後に、監視設計を“回る形”にするための定番をまとめます。

アラートに文脈を載せる

  • 対象(site/job)
  • 失敗phase(fetch/parse/store)
  • 直近の変化(成功率、429比率、0件率)
  • 推奨アクション(同時実行を下げる、再収集窓を回す等)

通知先を分ける

重大障害は即時(PagerDuty等)、品質劣化はSlack/メールのように分離し、ノイズを減らします。ハートビート監視サービスは通知チャネルを複数持てる旨が公式に説明されており、冗長化にも有効です。

監視の信頼性も監視

監視送信自体が失敗すると誤検知が増えます。Healthchecks.ioはping送信にタイムアウトやリトライを設定して堅牢性を上げる例(curlの--max-time--retry)を示しています。監視のための通信が、処理本体をブロックしない設計にしてください。


よくある失敗

  • ログが足りず切り分け不能:phaseとエラー分類がない
  • データ品質の監視がない:成功率だけ見て“空データ”を見逃す
  • リトライ無限:429に対して攻撃的になり、ブロックを悪化させる
  • 再実行が全量:二次障害(アクセス急増)を誘発する
  • 通知が多すぎる:軽微な揺らぎまで即時通知して疲弊する

監視設計を改善しませんか?

失敗検知から復旧までを運用に落とし込むには、指標設計と復旧手順の整備が重要です。現状の構成に合わせた監視・アラート設計の壁打ちも可能です。

お問い合わせスクレイピングに関するご相談・お見積もりはお気軽にどうぞ
相談する

まとめ

スクレイピング運用の監視設計は、稼働監視だけでなくデータ品質監視まで含めて初めて機能します。失敗パターンを分類し、ログ→メトリクス→アラートの順で設計し、再試行・バックオフ・隔離(DLQ)・差分再収集を組み合わせて復旧までを手順化してください。これにより「気づけない失敗」と「復旧が遅い運用」を同時に減らせます。

この記事を書いた人

Ibuki Yamamoto
Ibuki Yamamoto

Webスクレイピングエンジニア。10年以上の実務経験を持ち、大規模なデータ収集プロジェクトを数多く手がける。PythonとJavaScriptを得意とし、技術ブログでは実践的なスクレイピング手法を発信している。

データ収集のプロに
お任せください

年間1億件以上のデータ収集実績を持つプロフェッショナルチームが、大規模スクレイピング・アンチボット対策など、あらゆる課題を解決します。

1億+
年間データ収集件数
24/7
安定稼働
高品質
データ精度