【ITニュース解説】Your Scraper's Politeness Layer Deserves a Unit Test, Not a Prayer
2026年10月13日に「Dev.to」が公開したITニュース「Your Scraper's Politeness Layer Deserves a Unit Test, Not a Prayer」について初心者にもわかりやすく解説しています。
ITニュース概要
スクレイピング時、サーバーへの過度な負荷を防ぐ「礼儀正しい」アクセス制御は、設定任せにせずテストが必須だ。連続リクエストの最低間隔、429エラーや空の200応答への対応を単体テストで確認し、意図しないバーストや無限リトライを防ぐ。安定したスクレイピング運用には自動テストが不可欠である。
ITニュース解説
システムエンジニアを目指す皆さんにとって、ウェブサイトから情報を自動的に収集する「スクレイパー」というプログラムは、将来関わる可能性のある重要な技術の一つだ。スクレイパーは、ニュースサイトの記事やECサイトの商品情報など、インターネット上に公開されている大量のデータを効率的に集めるために利用される。しかし、この便利なツールを使う際には、一つ非常に大切な「マナー」を守る必要がある。それが「丁寧さの層(Politeness Layer)」と呼ばれる機能だ。
ウェブサイトは、私たちのプログラムがアクセスするためのサーバーというコンピュータで動いている。もし、スクレイパーが一度に何百、何千ものリクエストをサーバーに送りつけたらどうなるだろうか。サーバーは処理しきれなくなり、ダウンしてしまうかもしれない。これは、まるで多くのお客さんが一斉にお店に押し寄せて、お店が混乱してしまうようなものだ。これを防ぐために、スクレイパーには「丁寧さの層」が組み込まれる。これは、具体的には、リクエストとリクエストの間に一定の時間を空けたり(例えば、1.3秒待つ)、サーバーから「ちょっと待って」という信号(エラーコード429など)が来たときに、さらに待つ時間を長くしたりする仕組みのことだ。
ところが、この「丁寧さの層」は、しばしば軽視されがちだ。多くの開発者は、この層を単なる設定ファイル、つまりYAMLファイルなどに書かれた数字の羅列だと考えてしまう。そして、他の部分を修正する際に「邪魔だから」と、これらの数字を適当に調整してしまうことがある。例えば、リクエストの間隔を短くして、スクレイパーがウェブサイトに以前よりはるかに速い速度でアクセスするようになってしまう。結果として、スクレイパーはウェブサイトに過度な負荷をかけ、ウェブサイト側からブロックされたり、最悪の場合、法的な問題に発展したりすることもある。ウェブサイトとの「レート制限(Rate Limiting)」は、いわば「これ以上の速さでアクセスしないでください」というウェブサイトとの「契約」なのだ。契約は、それが守られているかをしっかりと確認する必要がある。
そこで重要になるのが、この「丁寧さの層」を「テスト」することだ。テストとは、プログラムが正しく動くかを確認する作業のこと。特に、スクレイパーの丁寧さの層は、ウェブサイトとの信頼関係に関わる部分だからこそ、入念なテストが求められる。記事では、具体的な三つのテスト方法が提案されている。
一つ目のテストは「フロアテスト」と呼ばれるものだ。これは、同じウェブサイトに対して連続してリクエストを送る際に、その間に実際にどれくらいの時間間隔があるかをチェックする。多くのスクレイパーは、平均してこれくらいの時間間隔がある、という設定を持っているが、平均値だけでは不十分だ。なぜなら、一時的に短時間で大量のリクエストを送り、その後長く休むような「バースト(突発的な集中)」が発生しても、平均値は問題なく見えてしまうからだ。このテストでは、最小の時間間隔が、設定した「最低限の丁寧な間隔」を下回っていないかを厳しく確認する。もし最小間隔が設定より短ければ、それはウェブサイトへの負担が増えている証拠であり、バーストが発生している可能性を突き止めることができる。例えば、テストコードでは、リクエスト間の最小間隔が、定義された最小値以上であることを確認している。
二つ目のテストは「429レスポンステスト」だ。ウェブサーバーは、スクレイパーが速すぎる場合に「429 Too Many Requests」(リクエストが多すぎます)というエラーコードを返したり、「Retry-After: 7」(7秒後に再度試してください)といった情報を含めたりすることがある。このテストでは、サーバーからこの「429」という応答が返ってきたときに、スクレイパーが適切に反応し、指定された時間(例えば7秒)以上待ってから次のリクエストを送るかを検証する。重要なのは、「いつか」ではなく「指定された時間以上」待つことだ。実際にこのテストを行うことで、あるスクレイパーでは、「429」の後に一度成功すると、待機時間がリセットされてしまい、再び速いペースでリクエストを送ってしまうというバグが見つかったという。これでは、ウェブサイトから「速すぎる」と注意されても、すぐにまた同じ過ちを繰り返してしまうことになる。
三つ目のテストは「空の200レスポンステスト」だ。これは少し巧妙なケースに対応する。一部のウェブサーバーは、レート制限を適用する際に、エラーコードの「429」ではなく、あたかも成功したかのように「200 OK」というステータスコードを返し、しかも中身(ボディ)が空っぽのレスポンスを返すことがある。スクレイパーから見れば「成功した」と見えるため、スクレイパーのダッシュボードには成功率100%と表示されてしまう。しかし実際には、データは何も取得できていない。このテストでは、もし連続して空の「200 OK」が返ってきた場合に、スクレイパーが「429」を受け取った時と同じように、リクエストのペースを落とすかどうかを確認する。これで、見かけ上の成功に騙されて、実際には何のデータも集められないという状況を防ぐことができる。
これらのテストは、実際のインターネットに接続して行う必要はない。開発環境で、ローカルに用意した「記録プロキシ」という仕組みを使って実行する。記録プロキシは、スクレイパーのリクエストを一時的に受け止め、それに対して事前に設定された応答(例えば「429」のエラーや空の「200 OK」)を返すことができる。これにより、実際のウェブサイトに負荷をかけずに、様々な状況をシミュレーションしてテストできるのだ。これは、クレジットカードの決済機能をテストする際に、実際にお金を払ってテストしないのと同じ理屈だ。
もちろん、テストは開発段階だけで終わるわけではない。本番環境で実際にスクレイパーが動いている間も、軽い形で監視を続ける。例えば、毎時間、各ウェブサイトへのリクエスト間の最小間隔を記録し、それが設定した値を下回った場合にアラートを出す仕組みを導入する。これにより、開発段階で発見できなかった問題や、時間が経つにつれて発生する「現実とのずれ」を検知できるようになる。
「丁寧さ」というものの定義は、時間とともに変わる可能性がある。ウェブサイトのrobots.txtファイルに書かれているクロール遅延の指示が変わったり、ウェブサイト側が「Retry-After」ヘッダを返す頻度や値が変わったりすることもあるだろう。また、スクレイパーを運用する側が許容するリスクの度合いも変化するかもしれない。しかし、定義が変わるからといってテストを省略する理由にはならない。むしろ、変化する定義を一つのファイルにまとめておき、テストがその定義を参照するようにすれば良い。「私たちは丁寧だった」という結果は、感覚的なものではなく、テストによって「グリーンチェックマーク(問題なし)」と示される、客観的な事実であるべきなのだ。このようにして、スクレイパーはウェブサイトとの健全な関係を保ちながら、目的のデータを安定して収集できるようになる。