Skip to content
Jul 6, 2026

Automation

How to solve CAPTCHAs in Selenium (Python)

CT

CaptchaSonic Team

Automation & Web Scraping

If you automate with Selenium WebDriver in Python, a captcha on a login or checkout page usually stops your script cold. This guide shows the clean way past it: ask CaptchaSonic for a fresh token over gRPC and inject it into the page — no image tiles, no brittle screenshotting.

TIP

This is the token flow. CaptchaSonic solves the challenge server-side and returns a g-recaptcha-response token you drop into the page. Your form submits as if a human passed.

Install

pip install captchasonic selenium
export CAPTCHASONIC_API_KEY=sonic_your_key_here   # dashboard → API Keys

The core flow

Three steps: read the sitekey, solve, inject.

import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from captchasonic import CaptchaSonic

client = CaptchaSonic(os.environ["CAPTCHASONIC_API_KEY"])

driver = webdriver.Chrome()
driver.get("https://example.com/login")

# 1. Read the sitekey from the page.
sitekey = driver.find_element(By.CSS_SELECTOR, "[data-sitekey]").get_attribute("data-sitekey")

# 2. Solve over gRPC (auto-polls, returns when ready).
result = client.solve_recaptcha_v2_token(
    website_url=driver.current_url,
    website_key=sitekey,
)
token = result["solution"]["gRecaptchaResponse"]

# 3. Inject the token and submit.
driver.execute_script(
    "document.getElementById('g-recaptcha-response').innerHTML = arguments[0];",
    token,
)
driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()

That's the entire integration. The SDK handles polling, retries, and error mapping, so your Selenium code stays about driving the page.

Handling the tricky cases

  • Invisible reCAPTCHA / callback binding. Many sites don't submit the form directly — they bind the token via a JavaScript callback (data-callback="onCaptcha"). Call it with the token instead of writing the textarea: driver.execute_script("onCaptcha(arguments[0])", token).
  • Token freshness. reCAPTCHA tokens live ~120 seconds. Solve as late as possible — right before the click, not at the top of your script.
  • Dynamic sitekeys. Read the sitekey from the live DOM at runtime instead of hard-coding it; it often changes between staging and production.
  • IP-locked validation. If the target checks that the token was solved from the same IP that submits it, pass a proxy= argument so CaptchaSonic solves through your IP.

Beyond reCAPTCHA

The same client solves Cloudflare Turnstile, GeeTest, AWS WAF, and image captchas — just swap the method (solve_turnstile_token, etc.). See the full list in the Python SDK reference.

Next steps