ほとんどのスクレイピングガイドは一つのことだけを最適化している。ブロックされずにデータを取得することだ。それは妥当な目標だが、パイプラインが最初の1か月を超えて生き残れるかどうかを決める部分を省いている。ターゲットに可能な限り高速にアクセスするスクレイパーは、単に無作法なだけではなく、脆弱でもある。サイトの負荷を急上昇させ、あらゆるレート制限やアンチボットルールを引き起こし、静かに読み取りたかったはずのソースを、積極的に自分を締め出そうとするものに変えてしまう。
直感に反する点は、責任あるスクレイピングの方法と、持続可能なスクレイピングの方法が同じものであることだ。制限を尊重し、負荷を分散させ、必要なものだけを求める、思いやりのあるクライアントのように振る舞うこと。それこそが検知の閾値を下回り続け、動作を続けられるプロファイルなのだ。これはブロックを回避する方法と同じコインのエチケット面にあたる。あの記事はボットに見えないようにすることについてで、この記事は有害な振る舞いをしないことについてだ。後者を実践すれば、前者はほとんど自然と実現される。
責任ある、持続可能なスクレイピングが実際にどのようなものかを見ていこう。
Read robots.txt, and take it seriously
適切に運営されているサイトはすべて、ルートにrobots.txtを公開しており、そこには自動クライアントが触れるべきでないパスと、場合によってはCrawl-delayが記されている。これは法的契約でもなければ技術的な障壁でもなく、サイトがその目的のために用意された唯一の場所で自らの希望を伝えているものだ。これを完全に無視することは、あなたが誠実な訪問者ではないという最も明確な兆候となる。
実践的な姿勢としては、実行開始時に一度robots.txtを取得してキャッシュし、提示するユーザーエージェントに対する禁止パスを尊重することだ。クロール遅延が指定されている場合は、それを提案ではなく下限として扱う。一部のプロジェクトがその一部から逸脱する正当な理由はあるが、「読んでいなかった」はその理由にはならない。robots.txtを読むことで、サイトがサイトマップをどこに置いているかも分かり、それはリンクを一つずつたどるよりもはるかに整った方法でURLを発見できることが多い。
Rate-limit yourself before the site has to
スクレイパーが行う中で最も有害な単一の行為は、ネットワークが許す限りの速さでリクエストを送ることだ。人間のトラフィック向けに規模設定されたターゲットは、たった一つの攻撃的なクライアントによって応答時間が悪化させられたり、それ以上の状態に陥ることがある。それは実際のユーザーに害を与え、あなたのIP範囲全体がブロックされる最も速い方法でもある。
意図的なリクエストレートを設定し、それを下回るようにする。ほとんどの作業では、ホストあたり1秒間に数リクエスト程度で十分であり、小規模なサイトではより遅い方が安全だ。固定されたメトロノームのような間隔ではなく、リクエストの間に小さなランダムジッターを加えることで、トラフィックが機械的に均一に見えないようにする。目標は、誰かの監視ダッシュボードに現れるスパイクではなく、多くの中の控えめな一人の訪問者になることだ。全体のスループットをもっと増やす必要がある場合は、単一のホストへの圧力を強めるのではなく、時間とローテーティングプールにわたって分散させる。
Back off when the site says no
429 Too Many Requestsや503は、サーバーが明示的に速度を落とすように伝えているものだ。間違った対応は即座に再試行することであり、それはまさに過負荷状態のサーバーが処理できないことだ。正しい対応は指数バックオフだ。つまり、待ってから再試行し、再度失敗したらさらに長く待ち、上限まで毎回遅延を倍にしていく。サーバーがRetry-Afterヘッダーを送ってきた場合はそれに従うこと。それはどれだけ待つべきかを正確に伝えている。
これは、本当に失敗したリクエストを再試行する場合とは異なる。接続の切断やタイムアウトは、速やかに再試行する価値のある失敗した試みだが、429は正常に動作しているサーバーが余裕を求めているものだ。両者は別に扱うべきだ。429を狭いループの中で盲目的に再試行することは、スクレイパーがソフトなレート制限をハードな禁止に変えてしまう原因となる。
Cache aggressively and never fetch the same thing twice
最も安価なリクエストは、送らないリクエストだ。規模を拡大する前に、どれだけ再取得しているかをよく確認しよう。レスポンスをキャッシュし、条件付きリクエストでETagとLast-Modifiedを尊重し、URLフロンティアの重複を排除することは、実際の運用でリクエスト量を大幅に削減することが多い。避けられたリクエストはすべて、ターゲットにかけなかった負荷であり、使わなかった帯域であり、決して起こらなかったブロックリスクの出来事だ。
これはコストと直接重なる部分だ。より軽い訪問者になるための同じ規律は、プロキシの帯域コストを削減することにもつながる。必要なページだけをリクエストし、使うフィールドだけを取得し、HTMLだけが欲しい場合は画像やフォントのようなアセットをスキップする。礼儀正しさと効率性は、同じ習慣の集まりなのだ。
Scrape during off-peak hours
作業の実行タイミングを制御できるなら、ターゲットが静かな時間に実行しよう。日中なら目立つバッチ処理も、サイトのローカルタイムゾーンでの深夜の低トラフィックの中では目立たなくなる。これは、サーバーが最も余裕のない時に負荷を追加することと、そうでなければ空いたままになっていたはずの余力を借りることの違いだ。大規模で定期的な取得については、自分の都合ではなく、ターゲットのオフピークの時間帯に合わせてスケジュールしよう。
Identify yourself honestly where you can
ここには実際の緊張関係があり、率直に述べておく価値がある。伝統的に、良いスクレイピングのエチケットとは、ボットの名前と連絡方法を記した説明的なUser-Agentを送ることを意味する。そうすれば、トラフィックに気づいた管理者は、ブロックする代わりに連絡を取ることができる。多くの真剣で正当なクローラーは、まさにこれを行っている。
同時に、サイトは振る舞いにかかわらず自動化されていると自己申告するものを次第にブロックするようになっており、それがスクレイパーを通常のブラウザとして振る舞う方向に押している。どちらの立場も、使用ケースによっては正当化できる。正当化できないのは、実際にはそうではない特定のサービスになりすますことや、他社のクローラーを詐称することだ。自分の状況に対して正直な提示方法を選び、それを一貫させよう。ビジネスのためにデータを収集しているなら、クローラーが何をしていて、どう連絡すればよいかを説明する公開ページを持つことにコストはかからず、多くの対立を防いでくれる。
Take only public data, and mind what is in it
責任あるスクレイピングとは、認証の壁を突破することなく、また同意した利用規約をその後無視することなく到達できる公開ページを対象とすることを意味する。ログインの背後にあるデータは、法的にも倫理的にも異なる区分に属し、スクレイピング自体が合法かどうかはその境界線に大きく依存する。その境界の公開側に留まろう。
データがどこから来たかと同じくらい、データに何が含まれているかにも注意を払おう。ページに個人情報が含まれている場合、それを保存した瞬間からプライバシーに関する義務を負うことになり、個人データを大規模に収集することはGDPRや同様の規制の対象となる。最も清潔な姿勢は、保持する具体的な合法的理由がない限り、個人データを収集対象から除外し、不要なものは保持しないことだ。
Where proxies fit, and why the good ones make you gentler
以上のことはいずれもプロキシに反対する議論ではなく、正しい使い方をするべきだという議論だ。質の高いレジデンシャルプールがあれば、一つのアドレスからターゲットに圧力を集中させる代わりに、妥当なリクエストレートを多数のIPと地域に分散させることができる。適切に使えば、それはサイトをより強く叩く方法ではなく、負荷分散とローカライゼーションのためのツールだ。
プールの質は、そもそもどれだけ再試行することになるかも左右する。良好なレピュテーションを持つクリーンなIPは、フラグを立てられたIPがチャレンジを受ける場面をすんなりと通過するため、より良いプールを使えば失敗する試みが減り、再試行が減り、同じデータを得るために生じる総負荷が少なくなる。セッションの途中で新しいIPに切り替えるのではなく、論理的な作業単位ごとに一つのアイデンティティを使う、賢明なローテーション(スティッキーとローテーティングの比較)を行うことで、あなたのフットプリントは一貫性を保ち、軽いままになる。そしてレイテンシーを低く保つことで、各リクエストが積み重なることなく、速やかに完了して解放される。
A short checklist
robots.txtを取得して尊重し、そこに示されたサイトマップを利用する。- ランダムジッターを加えた意図的なホストごとのレートを設定する。通常は1秒間に数リクエストで十分だ。
429/503に対しては指数バックオフを行い、Retry-Afterに従う。これを、失敗したリクエストの再試行と混同しないこと。- キャッシュし、条件付きリクエストを使い、重複を排除する。最も安価なリクエストは、スキップするリクエストだ。
- 必要なページとフィールドだけを取得し、使わないアセットはスキップする。
- 大規模な作業では、ターゲットのタイムゾーンでのオフピーク時間帯を優先する。
- 正直で一貫したアイデンティティを選ぶ。他社のクローラーになりすますことは決してしない。
- 公開データのみを対象とする。保持する合法的な理由がない個人データは対象外とする。
- クリーンなレジデンシャルプールを、負荷を強めるためではなく、分散させるために使う。
The bottom line
何年も動き続けるスクレイパーは、最も攻撃的なものではなく、ターゲットにほとんど気づかれないものだ。ここで挙げた実践、レート制限、バックオフ、キャッシュ、オフピークのスケジューリング、正直な識別は、すべて同じ方向を指している。必要なものだけを取得し、サイトを健全な状態に保ち、実際にそうであるべき思いやりのあるクライアントのように見えることだ。それが倫理的なスクレイピングの方法であり、たまたまブロックされない方法でもあるのだ。
負荷を集中させるのではなく分散させるために構築されたインフラをお探しなら、当社のレジデンシャルプロキシはクリーンでローテーティングするプール上で動作しており、料金ページにはGBごとのプランが用意されているため、より軽く、より賢いスクレイピングは実際にコストを抑えられる。