青色に照らされたサーバーブレードが並ぶデータセンター
現場の実践

n8n×Playwrightのスクレイピング基盤を本番監視する観点整理

目次を見る

スクレイピング用のバッチ処理をn8n(ノーコードで自動化ワークフローを組めるツール)とPythonで組んでいる、あるいはこれから構築しようとしている運用担当者に向けた内容です。データ収集パイプラインが動いた・動かないだけで評価されがちですが、本番運用では監視設計と障害切り分けの観点が欠けると後から痛い目を見ます。

具体的には、ヘッドレスブラウザ(画面を描画せずに動くブラウザ)によるDOM取得処理をPythonのワーカーで実行し、n8nが再試行やキュー管理を担当する構成が近年増えています。この構成はオンプレで動かすBeautifulSoup単体のスクリプトに比べて可用性は上がりますが、監視すべきポイントも増えます。どこを見ておけば障害の予兆を掴めるか、整理していきます。

なぜ今この構成が増えているのか

数年前まで、Webサイトから企業情報を抽出する処理は静的HTTPリクエストとBeautifulSoup(HTMLを解析するPythonライブラリ)の組み合わせで十分でした。

しかし現在は多くのサイトがNext.jsやNuxtといったフレームワークでクライアント側にデータを描画する方式(ハイドレーション)を採用しています。単純なHTTPクライアントは空のHTMLシェルしか取得できず、スクレイパーが無言で失敗します。

この問題への対応として、PlaywrightというヘッドレスブラウザをPythonから操作し、JavaScriptの実行を待ってからDOMを取得する構成が使われるようになりました。あわせて、プロキシのローテーションやリトライのバックオフ、CRMへの出力ロジックを1本のモノリシックなスクリプトに詰め込むと、DOM構造が少し変わっただけでバッチ全体が止まるという問題も指摘されています。

アーキテクチャの段階的な分解

この種の構成は3つの層に分離されています。それぞれの層で障害の種類が異なるため、監視設計もレイヤーごとに考える必要があります。

1つ目はヘッドレスワーカー層です。PythonとPlaywrightが隔離されたコンテナで動き、ステルスなブラウザコンテキスト(自動操作だと検知されにくい設定済みのブラウザセッション)を作り、スクロールなどの擬似操作でページを描画させてからDOMを抽出します。

2つ目はオーケストレーション層です。n8nがレート制限のキュー管理、再帰的なページネーション(次ページへの巡回)の状態管理、指数バックオフ付きの失敗リトライ、Webhook経由での結果配送を担当します。

3つ目はデータ整合性層です。Pydantic(Pythonの型検証ライブラリ)が電話番号をE.164形式(国際電話番号の標準フォーマット)に正規化し、メールアドレスを検証し、不正なURLを弾いてからDB書き込みに回します。

従来型アーキテクチャとの比較で見る運用負荷の変化

オンプレで1本のスクリプトをcronで回していた時代は、障害対応はシンプルでした。ログを見てスクリプトが落ちた箇所を特定すればよいだけです。

一方、ワーカー・オーケストレーター・バリデーション層に分離した構成では、障害点が3箇所に分散します。n8nのワークフロー実行履歴は正常なのに、Python側のFastAPIエンドポイントがタイムアウトしているケースもあれば、取得自体は成功してもPydanticのバリデーションで全件弾かれているケースもあります。

これはマイクロサービス的な構成にありがちな「個々は動いているのに全体の出力がゼロ件」というタイプの障害です。クラウド移行でモノリスをサービス分割した経験がある方には馴染みのあるパターンだと思います。

監視ツールとしては、n8nのワークフロー実行ログ(Executionsタブ)、FastAPIワーカー側のアプリケーションログ、そしてPostgreSQLなど書き込み先のレコード件数推移を別々に見る必要があります。どれか1つだけを見ていると、障害の全体像を見誤ります。

障害の根本原因分析で確認すべき3つのポイント

実際に運用を始めたら、まず以下の観点で定期確認できる体制を作ることをおすすめします。

  • n8nの実行履歴で失敗ノードを確認する: ワークフローエディタの「Executions」からエラーの発生ノードと直前の入力データを確認できます。DOM取得ノードで落ちているのか、Webhook配送で落ちているのかを切り分けます
  • Playwrightワーカーのタイムアウト設定を見直す: headless起動時のtimeoutパラメータやページ遷移待機の設定が短すぎると、サイト側の表示が重い時間帯にだけ失敗する「間欠障害」になります
  • Pydanticバリデーションの失敗率を記録する: 取得件数に対してバリデーション通過件数が急減した場合、対象サイトのDOM構造が変わった可能性が高いです。失敗理由をログに残しておくと、どのフィールド(電話番号・メール・URLなど)で弾かれているか特定できます

これらに加えて、対象サイト側のレート制限やボット検知の強化によって、ある日突然空のHTMLシェルしか返らなくなるケースもあります。これは自社側のコード変更がなくても起きる障害のため、「取得件数0件」のアラートだけは必ず設定しておくべきポイントです。

運用コストの観点で見ておきたいこと

この構成はコンテナで動かすことが前提になるため、クラウド移行を検討する際はPlaywrightワーカーのリソース消費を事前に見積もる必要があります。

ヘッドレスブラウザはメモリ消費が大きく、同時実行数を増やすとコンテナのメモリ上限に達しやすい性質があります。Kubernetes上で動かす場合は、Podのメモリリクエストと実際の消費量をkubectl top podなどで定点観測し、OOMKilled(メモリ不足による強制終了)が起きていないか確認してください。

また、商用のデータベンダーが月額で高額な請求を行う背景には、プロキシ維持やアンチボット回避の継続的なメンテナンスコストがあります。自前でこの構成を運用する場合も、プロキシサービスの利用料や、サイト構造変更への追随作業が継続的な運用コストとして発生する点は見込んでおく必要があります。

まとめ

n8nとPlaywrightを組み合わせたスクレイピング基盤は、単一スクリプトに比べて柔軟性と可用性が上がる一方、監視すべきポイントが3層に分散します。

導入前、あるいは運用の見直し時には次の点を確認してみてください。

  • n8nの実行履歴・Pythonワーカーのログ・DB書き込み件数を別々に可視化できているか
  • 「0件取得」や「バリデーション失敗率の急増」をアラート条件に含めているか
  • コンテナのメモリ消費とPlaywrightの同時実行数のバランスを把握しているか

これらを押さえておくと、障害発生時に「どの層で何が起きたか」を素早く切り分けられる状態に近づきます。

参考

How I Built an Autonomous B2B Directory Scraping & Enrichment Pipeline with n8n and Python

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。