Python で PopularCaptcha を解決する方法(動作する例、2026)
Python のスクリプトで PopularCaptcha に遭遇したなら、専用のブラウザファームも、自前のモデルも必要ありません。必要なのはページの sitekey と、1回の POST リクエスト、そして返ってくるトークンだけです。
このガイドでは、約5分で動くトークンを得るまでを扱います。API キーを取得し、sitekey を見つけ、トークンを要求し、フォームに送信し、スクリプトを無人で動かしたときに現れる失敗ケースを処理します。失敗した解決は無料なので、リトライで失うのは時間だけです。
Scarnox は、プロキシなしでも、自分のプロキシを使っても、PopularCaptcha を今日解決します。reCAPTCHA、Cloudflare Turnstile、AWS WAF などの他のキャプチャ種別は近日公開予定のため、ここの例はすべて PopularCaptcha を使っています。他の種別の違いはキャプチャの種類の概要で説明しています。
1. API キーを取得する
アカウントを作成して、クレジットカード不要の無料トライアルクレジットから始めてください。API キーはダッシュボードにあります。キーはソースコードに入れず、環境変数から読み取ってください。
export SCARNOX_KEY="scarnox_YOURAPIKEY"
2. sitekey を見つける
キャプチャのあるページを開き、DevTools を開いて、Elements パネルで data-sitekey を検索してください。PopularCaptcha の sitekey は UUID です。
<div class="h-captcha" data-sitekey="10000000-ffff-ffff-ffff-000000000001"></div>
HTML に data-sitekey がない場合、ウィジェットは JavaScript によって描画されている可能性があります。Network タブでウィジェットの設定のリクエストを確認してください。その sitekey クエリパラメーターが必要な値です。他の見つけ方では、iframe の URL やインビジブルなウィジェットについて扱っています。
site_url には、ウィジェットを表示しているページの URL を送ってください。ホストが最も重要ですが、ページの完全な URL を送るのが安全な選択です。
3. トークンを要求する
import os
import requests
API_URL = "https://api.scarnox.com/api/tasks/create"
API_KEY = os.environ["SCARNOX_KEY"]
def solve_captcha(sitekey: str, page_url: str) -> str:
r = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"captcha_type": "PopularCaptchaTaskProxyless",
"site_key": sitekey,
"site_url": page_url,
},
timeout=185, # この呼び出しはトークンの準備ができるまでブロックする
)
data = r.json()
if data.get("errorId") != 0:
raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
return data["solution"]["token"]
if __name__ == "__main__":
token = solve_captcha("10000000-ffff-ffff-ffff-000000000001", "https://example.com/signup")
print(token[:40], "...")
これが統合のすべてです。ポーリングのループも、2つ目の「結果を取得する」呼び出しもありません。リクエストはトークンの準備ができたときに返ります。そのため重要な設定は、遅い解決をカバーできるだけの長いタイムアウトだけです。約185秒を使ってください。
成功した応答では errorId が 0 になり、トークンは solution.token に入っています。それ以外の errorId は解決が失敗したことを意味し、応答には理由を示す errorCode と errorDescription が含まれます。
4. トークンを送信する
トークンは、サイトがキャプチャの応答を期待する場所に入れます。PopularCaptcha の場合、ほとんどは h-captcha-response というフォームフィールドです。多くのサイトは g-recaptcha-response も受け入れるため、両方を送ってください。
import requests
def sign_up(session: requests.Session, form_url: str, email: str, sitekey: str) -> requests.Response:
token = solve_captcha(sitekey, form_url)
return session.post(form_url, data={
"email": email,
"h-captcha-response": token,
"g-recaptcha-response": token,
}, timeout=30)
ここで重要な点は二つあります。実際のサイトは、ページ読み込み時のセッションクッキーも確認することが多いため、投稿する前に同じ requests.Session でフォームを読み込んでください。また、投稿先はページの URL ではなく、フォームの action URL です。両者が常に同じとは限りません。
送信の直前に解決してください。トークンは約2分以内に期限が切れるため、長いジョブの開始時に取得して保持しておかないでください。サイトがトークンを拒否する場合は、DevTools でフォームを開き、隠しフィールドの名前を確認してください。
5. 失敗を処理する
解決の失敗は無料なので、リトライは時間だけがかかります。ただし、リトライでも決して成功しないエラーもあるため、盲目的にループしないでください。毎回 errorId を確認し、errorCode と errorDescription を記録して、一時的な失敗だけをリトライしてください。
ネットワークエラーは別に扱う必要があります。requests は、応答が存在する前に例外を投げるためです。
import requests
try:
token = solve_captcha(sitekey, page_url)
except requests.RequestException as exc:
print("network problem, retry later:", exc)
except RuntimeError as exc:
print("solve rejected:", exc)
バックオフとジッターを備えた完全なリトライポリシーは、エラー処理のガイドにあります。
よくある間違い
- **
site_urlが間違っている。** ホームページではなく、ウィジェットを表示しているページを送ってください。 - 古いトークン。 約2分を過ぎて使ったトークンは拒否されます。送信の直前に解決してください。
- セッションがない。 ページのクッキーなしで投稿すると、有効なトークンでも失敗することがあります。
- **一部のサイトは
rqdataが必要。** ウィジェットのためにページがrqdataの値を提供している場合は、オプションのrqdataフィールドとしてリクエストに含めてください。 - インビジブルなウィジェット。 チェックボックスがなく、サイトが自身のコードからウィジェットを起動する場合は、リクエストに
"is_invisible": trueを加えてください。トークンの返し方はインビジブルキャプチャのガイドにあります。
無料で試す
アカウントを作成して、クレジットカード不要の無料トライアルクレジットから始めてください。より大きなジョブに組み込む前に、自分が所有するフォームに対して上の例を実行してください。大量に解決した場合の費用は、現在の料金ページをご覧ください。
解決のログ
解決1回につき1行のログを残してください。sitekey、ページのホスト、errorId、失敗時の errorCode、呼び出しにかかった時間です。API キーやプロキシのパスワードは含めないでください。これらのログを見ると、実行が遅いのがページのせいか、プロキシのせいか、ソルバーのせいかが分かります。サポートに問い合わせる場合にも、最初に必要になる情報です。
ループでの解決
スクリプトが連続して多数のキャプチャを解決するなら、ループは単純に保ってください。解決し、送信し、結果を確認してから、次に進みます。事前に解決してトークンをキューに入れてはいけません。各トークンは約2分以内に期限が切れるからです。同じサイトへの解決の間に短い間を置くと、リクエストの頻度は人間が行う程度に近くなります。