Scarnox · Blog

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)

バックオフとジッターを備えた完全なリトライポリシーは、エラー処理のガイドにあります。

よくある間違い

無料で試す

アカウントを作成して、クレジットカード不要の無料トライアルクレジットから始めてください。より大きなジョブに組み込む前に、自分が所有するフォームに対して上の例を実行してください。大量に解決した場合の費用は、現在の料金ページをご覧ください。

解決のログ

解決1回につき1行のログを残してください。sitekey、ページのホスト、errorId、失敗時の errorCode、呼び出しにかかった時間です。API キーやプロキシのパスワードは含めないでください。これらのログを見ると、実行が遅いのがページのせいか、プロキシのせいか、ソルバーのせいかが分かります。サポートに問い合わせる場合にも、最初に必要になる情報です。

ループでの解決

スクリプトが連続して多数のキャプチャを解決するなら、ループは単純に保ってください。解決し、送信し、結果を確認してから、次に進みます。事前に解決してトークンをキューに入れてはいけません。各トークンは約2分以内に期限が切れるからです。同じサイトへの解決の間に短い間を置くと、リクエストの頻度は人間が行う程度に近くなります。

次のステップ