🕷️

Sentryを使ったScrapyのウェブクローリング監視

2023/09/03に公開

クローリング監視の必要性

ウェブサイトのクローリングは、インターネット上の情報を自動的に収集する方法です。機械学習の文脈では、言語モデルや辞書作成などのデータの収集に欠かすことができません。必要な質および量のデータを収集するためには、定期的かつ大規模なクローリングが必要となります。

さて、クローリングを実装し運用する上で問題となるのが、エラーの対応です。インターネットを通じてウェブページをクローリングする際には、以下のような問題が偶発的に発生します。

  • ネットワーク的な問題でリクエストがタイムアウトする
  • リクエスト先のサーバの問題で、正常にHTMLが読み込まれない
  • ウェブページの構造が変わってしまい、意図した抽出処理が失敗する

上の2つは実行時の外部環境に起因するため時間を空けたり再実行することで解決することがありますが、最後の1つは外部環境の変化に対して自身のコードが対応できていない問題であり、修正しない限り再発し続けます。

こうした異常に対して運用者が素早く気付き、リトライや処理の修正を行う必要があります。しかし、クローリングは定期的かつ高頻度に実行されるものであり、いつ起こるか分からないエラーに対して常に気を配る必要があり、エラー発生時に逐一確認するのはなかなか大変です。また、そもそも後から検証しても再現しないことがあり、実際にエラーが起きたときの状況を詳細なログとして残しておく必要があります。

そこでこの記事では、Sentryを利用してScrapyの実行中に起きたエラーを記録するための方法を紹介します。ScrapyはPythonで実装されたクローリングフレームワークです。ページネーションを遡ることや再帰的なクローリングが可能など様々な機能が実装されており、シンプルな用途から本格的なクローリングの構築が可能です。このクローリングフレームワークにSentryを組み合わせることで、コードベースへの少ない修正でクローリング運用およびエラー監視が可能になります。なお、Scrapyでなくても自作のクローリングにもSentryは適用できます。

Sentryの導入

Sentryはアプリケーション監視のSaaSです。公式が提供する簡単なSDKを導入するだけで、エラーが発生したときにエラー内容とともに詳細なスタックトレースや実行時の変数の中身、実行環境などの各種情報を収集できます。また、Slack通知や他サービスとのインテグレーションも容易です。

Sentryのアカウント作成&プロジェクト作成

まずはSentryのアカウントを作成し、プロジェクト作成などの初期設定を済ませておきます。このあと「DSNコード」と呼ばれる文字列が必要になりますので、管理画面から取得しておきます。

Scrapyのコード内で設定する

ここではScrapyの具体的な実装はできているものと仮定し、SentryのSDKの導入のみを記述します。

まずsentry-sdkをインストールします。

# with pip
$ pip install sentry-sdk

# with poetry
$ poetry add sentry-sdk

scrapyの実行時にsentry-sdkの設定が実行されるように、settings.pyの下部に以下のように記述します。

import os
import sentry_sdk
sentry_sdk.init(
    dsn=os.getenv("SENTRY_DSN", ""),
)

ここでsentry-sdkの初期化時に、さきほどSentryの管理画面で取得したDSNコードを指定します。コードベースにこのDSNコードをハードコードしたくないので、環境変数からSENTRY_DSNの値を読み込んでいます。実行時に環境変数を設定してもいいですが、.envに記載してdotenvを使うか、poetryの場合はpoetry-dotenv-pluginで自動で読み込むように設定しておくと便利です。

# .env
SENTRY_DSN=https://hoge.sentry.io/00000000

これで準備は完了です。特にエラーとなりそうな部分にコードを追記するといた必要なくエラー監視を導入することができるのが、Sentryの優れている点と言えます。

監視

あとはscrapyを実行するだけです。エラーが発生すれば、下記のようにSentryに情報が蓄積されていきます。エラーの種類ごとに集約してIDを発番してくれるので、エラーごとに状況の確認と原因調査ができます。

(コードや処理名にクロール対象の名前が含まれるため、下記スクリーンショットでは適宜マスキングしています)

それでは、この中からエラーの一つを見てみます。エラーの内容および実行時の環境、発生タイミングや発生頻度などの様々な統計情報が可視化されています。例えば、右カラムの「Last 24 Hours」では1時間毎の発生頻度が表示されていますが、実行時刻によって件数に差があることがわかります。

また、以下のようにスタックトレースも追うことが可能です。実装したコードのどの箇所で落ちているかがわかり、その部分の処理自体に問題があるのか、それとも入ってくる情報が間違っているのかといった問題の切り分けが可能です。この場合、responseに書かれているXMLのURLを読み込んで処理する際に、レスポンスがjsonで返ってきていることでパースに失敗していそうなことがわかります。

このようにエラーをSentryで確認し適宜対応していくことで、バグを潰したり意図しないエラーに対応していくことが可能です。

おわりに

この記事ではSentryを使ってScrapyのクローリングを監視する方法を紹介しました。ウェブサイトのクローリングは外部要因によってエラーが偶発的に起きるものであり、そうした対策にSentryのようなアプリケーション監視は有用です。

Discussion