Selenium キャプチャソルバー(Python): 動作する例(2026)
Selenium は本物のブラウザを動かすため、ページは描画され、スクリプトは人が使うのと同じように動きます。Selenium にできないのは、PopularCaptcha のウィジェットを解くことだけです。このガイドではそのステップを加えます。描画されたページから sitekey を読み取り、1回の API 呼び出しでトークンを取得し、フォームに書き込んで、送信します。
扱うのは PopularCaptcha のウィジェットで、Scarnox が今日プロキシなしで解決します。無料トライアルクレジットから始めましょう。クレジットカードは不要です。まずはテストフォームでスクリプトを試してください。
Selenium がすること
フローは四つの部分からなります。
- ページを読み込み、ウィジェットが描画されるのを待つ。
- ウィジェットの
data-sitekey属性を読み取る。 - API からトークンを取得し、フォームに入れる。
- トークンの期限が切れる前にフォームを送信する。
キャプチャに触れるのは三つ目のステップだけです。それ以外はすべて通常の Selenium の作業です。
パッケージのインストール
pip install selenium requests
Selenium 4.6 以降は、一致する ChromeDriver を自動的に見つけるため、ドライバーを手動でダウンロードする必要はありません。
スクリプト全体
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
API_KEY = "scarnox_YOURAPIKEY"
API_URL = "https://api.scarnox.com/api/tasks/create"
PAGE_URL = "https://example.com/signup"
def solve(sitekey: str, page_url: str, invisible: bool = False) -> str:
body = {
"captcha_type": "PopularCaptchaTaskProxyless",
"site_key": sitekey,
"site_url": page_url,
}
if invisible:
body["is_invisible"] = True
r = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}"},
json=body,
timeout=185, # トークンの準備ができるまでブロックする
)
data = r.json()
if data.get("errorId") != 0:
raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
return data["solution"]["token"]
INJECT_TOKEN_JS = """
const token = arguments[0];
let field = document.querySelector('[name="h-captcha-response"]');
if (!field) {
field = document.createElement("textarea");
field.name = "h-captcha-response";
field.style.display = "none";
document.querySelector("form").appendChild(field);
}
field.value = token;
let extra = document.querySelector('[name="g-recaptcha-response"]');
if (!extra) {
extra = document.createElement("textarea");
extra.name = "g-recaptcha-response";
extra.style.display = "none";
document.querySelector("form").appendChild(extra);
}
extra.value = token;
"""
def main() -> None:
driver = webdriver.Chrome()
try:
driver.get(PAGE_URL)
widget = WebDriverWait(driver, 15).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "[data-sitekey]"))
)
sitekey = widget.get_attribute("data-sitekey")
invisible = widget.get_attribute("data-size") == "invisible"
token = solve(sitekey, driver.current_url, invisible=invisible)
# 他のフィールドを先に埋め、送信の直前にトークンを注入する。トークンの有効期限は約2分です。
driver.find_element(By.NAME, "email").send_keys("you@example.com")
driver.execute_script(INJECT_TOKEN_JS, token)
driver.find_element(By.CSS_SELECTOR, "form button[type=submit]").click()
WebDriverWait(driver, 15).until(EC.url_changes(PAGE_URL))
print("Submitted. Now at:", driver.current_url)
finally:
driver.quit()
if __name__ == "__main__":
main()
プロキシなしの PopularCaptcha の解決には、プロキシは必要ありません。プロキシのフィールドは省き、サイトからは通常の接続が見えるようにしてください。
操作の順序は、最もよく失敗する部分です。他のフォームのフィールドを先に埋め、次に解決し、注入し、クリックしてください。他のフィールドに入力する前に解決すると、遅いページや遅いフォームによって送信がトークンの寿命を超えてしまうことがあります。解決からクリックまでの間隔はできるだけ短く保ち、クリック後は結果のページでエラーがないかを確認してから、キャプチャが通過したと判断してください。
トークンを JavaScript で注入する理由
ほとんどの PopularCaptcha のウィジェットは、人が解いたときに、h-captcha-response という名前の隠しテキストエリアにトークンを書き込みます。Selenium は人を見ていないため、スクリプトが同じフィールドに自分で書き込みます。INJECT_TOKEN_JS のスニペットは二つのことをします。
- ウィジェットがすでに作成している場合は、そのテキストエリアを再利用します。
- ページが作成していなければ、テキストエリアを作成して、フォームに追加します。
また、多くのサイトは互換性のために g-recaptcha-response という名前を読むため、そちらも埋めます。
インビジブルなウィジェット
インビジブルなウィジェットにはチェックボックスがありません。背景で動作し、通常はフォームの送信時に起動します。スクリプトは data-size="invisible" を確認し、それを見つけると is_invisible: true を送ります。一部のサイトは、ウィジェットに JavaScript のコールバックを付けています。トークンを注入してもフォームが動かない場合は、data-callback 属性を探し、その関数をトークンで呼び出してください。このケースについてはインビジブルキャプチャのガイドで扱っています。
テストで使う
Selenium は、E2E テストでも一般的に使われるツールです。自分のステージングサイトがキャプチャを表示する場合、同じコードでテストを通せます。テスト環境は本番と分け、自分が所有していないサイトに対しては実行しないでください。テストスイートの設定は自動テストでのキャプチャにあります。
よくある問題
- ウィジェットが表示されない。 待ち時間を増やすか、ウィジェットが iframe の中にないかを確認してください。iframe の中にある場合は、まず
driver.switch_to.frame(...)でフレームに切り替えてください。 - フォームは送信されるが、サイトがトークンを拒否する。 トークンを、ウィジェットが表示されたページに送っているかを確認してください。
driver.current_urlは、クエリ文字列を含め、ページの実際の URL と一致している必要があります。 - トークンの期限が切れた。
solveの呼び出しを送信ステップの近くに移動してください。トークンは約2分間有効です。 - API のタイムアウトエラー。 スクリプトのように、約185秒のタイムアウトを使ってください。リトライのロジックはキャプチャソルバーのエラー処理で扱っています。
料金
課金は成功した解決ごとで、失敗した解決は課金されません。料金は現在の料金ページをご覧ください。無料トライアルクレジットから始めましょう。クレジットカードは不要です。