ウェブスクレイピングとキャプチャ: なぜ出るのか、どう対処するか
スクレイピング中にキャプチャが出るのは、サイトがリクエストを自動化されたものと判断したときです。よくある要因は、短時間に多すぎるリクエスト、評判の悪い IP アドレス、ブラウザの信号の欠如、またはサイトがより厳しく守っているページへのアクセスです。実務的な対応は三つのステップからなり、この順序で行います。要因を減らす、コードでキャプチャを検出する、避けられないキャプチャを解決する、です。このガイドでは各ステップを扱い、残りについては詳細なガイドを案内します。
サイトがスクレイパーにキャプチャを出す理由
サイトは、ページのリクエスト時点で人間とスクリプトを見分ける手段がほとんどないため、パターンを見ています。スクレイパーは次のような点で目立ちがちです。
- 人がクリックできるよりも速くリクエストを送る。
- 間を空けずに同じパスを繰り返す。
- 家庭用ネットワークではなく、データセンターのアドレスから来る。
- 一般的なブラウザと一致しないヘッダーを送る。
- リクエストの間でクッキーやセッションの状態を保持しない。
どれか一つでも十分な場合があります。キャプチャは、サイトがそれ以上のページを提供する前に、人間らしい手順を求めるための方法です。パターンを減らすと、キャプチャも減ることが多く、それは解決するよりも安上がりです。
コードでキャプチャを検出する
何かを解決する前に、取得したページがそもそもキャプチャのページかどうかを確認してください。単純なテストは、ウィジェットのマークアップを探して sitekey を読み取ります。
import re
import requests
SITEKEY_RE = re.compile(r'data-sitekey="([0-9a-f-]{36})"')
def fetch(url: str) -> dict:
resp = requests.get(
url,
timeout=30,
headers={"User-Agent": "ExampleBot/1.0 (+https://example.com/bot)"},
)
html = resp.text
if "h-captcha" in html or "g-recaptcha" in html:
match = SITEKEY_RE.search(html)
return {"captcha": True, "sitekey": match.group(1) if match else None, "html": html}
return {"captcha": False, "sitekey": None, "html": html}
page = fetch("https://example.com/search?q=shoes")
if page["captcha"]:
print("captcha found, sitekey:", page["sitekey"])
h-captcha と g-recaptcha という文字列は、ページが使うマークアップにすぎないため、これは保証ではなくシグナルです。sitekey が見つからない場合は、キャプチャの sitekey の見つけ方を参照してください。
避けられないキャプチャは解決する
PopularCaptcha のウィジェットがページにあり、その sitekey がわかっているなら、Scarnox API に対して1回の POST リクエストでトークンを要求し、h-captcha-response フィールドに送信できます。エラー処理を含む完全な関数は、Python から1回のリクエストでキャプチャを解決するにあります。トークンは約2分で期限が切れるため、受け取ったらすぐに使ってください。タイミングの詳細はキャプチャトークンの期限切れにあります。
Scarnox が現在ライブでサポートしているのは PopularCaptcha で、プロキシなしと自分のプロキシを使う方式の両方があります。reCAPTCHA v2 と v3、Cloudflare Turnstile、GeeTest、AWS WAF、Arkose は近日公開予定です。対象がそれらのいずれかを使っている場合、キャプチャのガイドで一般的な選択肢は説明していますが、ライブでない解決の上に本番のフローを構築しないでください。
ブロックされたページごとの判断フロー
スクレイパーがキャプチャに遭遇したら、単純な判断の順序を守ると、ジョブを正直に保ち、リクエストの量も抑えられます。
- 代わりに使えるデータソースはあるか。 必要なフィールドを API、フィード、エクスポートでカバーできるなら、そちらに切り替え、そのページへのリクエストは止めてください。
- robots.txt はそのパスを許可しているか。 許可していなければ、スキップしてください。立ち入らないよう求められているページのキャプチャを解決しないでください。
- 送りすぎたり、速すぎたりしていないか。 より長く止まり、レートを下げて、後で再確認してください。多くのキャプチャは、ペースを落とすと解消します。
- そのキャプチャはライブの種別か。 PopularCaptcha なら、このガイドの解決が適用されます。近日公開予定の種別なら、ジョブは一時停止して、リリースを監視してください。
- そのページは自動化してよいページか。 不明確なら、先に進む前にサイトの所有者に確認してください。
四つ目のステップは、最も見落とされやすいものです。ソルバーは、キャプチャの種別がサポートされているときにのみ役立ち、サポートされていない種別をリトライするジョブは、時間とリクエストを無駄にします。
ループではなくジョブの中でキャプチャを扱う
解決はトークンが必要なコードパスの中に置き、ジョブが各キャプチャをログに記録し、あるページが失敗し続けたら止まり、次に進めるようにしてください。キャプチャのページを要求し続ける無限ループは、サイトのファイアウォールに自分のアドレスを永久にブロックさせる最も速い方法です。
失敗を監視する
キャプチャを返したページの数を、URL ごと、時間帯ごとに記録してください。キャプチャが、サイトの一つのセクションだけで出る、あるいは一定数のリクエストの後にだけ出るなら、それが要因の場所を示しています。その情報は、より速いソルバーよりも役立ちます。何を変えるべきかを示してくれるからです。
やってはいけないこと
- サイトの制限を避けるために、多数の IP アドレスをローテーションしないでください。それは回避であり、速度を落とせという要求を争いに変えてしまいます。
- 使用を認められていない認証情報でログインの背後にあるページをスクレイピングしないでください。
- アカウントを作成したり、スパムを投稿したり、数量限定の商品を買ったりするためにキャプチャを解決しないでください。
責任を持ったスクレイピング
- スクレイピングを始める前に、サイトの
robots.txtと利用規約を読んでください。禁止されているパスと、指定されたクロール遅延を尊重してください。 - User-Agent で、連絡先を含めて、自分のボットを正直に名乗ってください。
- リクエスト頻度は低く保ってください。キャプチャは、サイトが速度を落とすよう求めている場合が多いです。
- サイトが止めるよう求めたら止め、停止を求められたブロックを回避しないでください。
- 個人データは、自分に適用されるプライバシーのルールに従って扱い、必要なものだけを収集してください。