How to Bypass reCAPTCHA When Web Scraping in 2026

How to Bypass reCAPTCHA When Web Scraping in 2026

Google’s reCAPTCHA remains one of the most widely deployed bot detection systems on the web. Whether you’re dealing with the checkbox challenge (v2), invisible scoring (v3), or the newer enterprise version, reCAPTCHA can halt your scraping pipeline entirely.

This guide covers practical methods to bypass reCAPTCHA during web scraping, with working Python code and an honest assessment of what works in 2026.

Understanding reCAPTCHA Versions

reCAPTCHA v2 (Checkbox)

The “I’m not a robot” checkbox. Clicking it triggers a risk analysis — if Google’s confident you’re human, it passes. If not, you get image selection challenges (“Select all traffic lights”).

reCAPTCHA v2 Invisible

Same technology as v2, but triggered automatically without a visible checkbox. It runs in the background and only shows challenges to suspicious users.

reCAPTCHA v3 (Score-Based)

No challenges at all. reCAPTCHA v3 silently scores every visitor from 0.0 (bot) to 1.0 (human). The website decides what score threshold triggers blocking. This is the hardest version to bypass because there’s no challenge to solve — you need to appear human from every angle.

reCAPTCHA Enterprise

Google’s paid offering combines v2 and v3 capabilities with additional signals and stricter detection. It includes bot score reason codes and adaptive risk analysis.

Method 1: CAPTCHA Solving Services

The most reliable approach for reCAPTCHA v2 is outsourcing the challenge to a solving service. These services use a combination of human workers and AI to solve CAPTCHAs and return the response token.

Using 2Captcha for reCAPTCHA v2

import requests
import time

API_KEY = "your_2captcha_api_key"

def solve_recaptcha_v2(site_key, page_url):
    # Submit the CAPTCHA
    submit_resp = requests.post("https://2captcha.com/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": site_key,
        "pageurl": page_url,
        "json": 1
    }).json()

    if submit_resp["status"] != 1:
        raise Exception(f"Submit failed: {submit_resp}")

    task_id = submit_resp["request"]
    print(f"Task submitted: {task_id}")

    # Poll for result
    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://2captcha.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1
        }).json()

        if result["status"] == 1:
            return result["request"]
        elif result["request"] != "CAPCHA_NOT_READY":
            raise Exception(f"Solve error: {result}")

    raise TimeoutError("CAPTCHA solving timed out")

# Get the site key from the page HTML
# Look for: data-sitekey="6Le..." in the reCAPTCHA div
site_key = "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
page_url = "https://example.com/login"

token = solve_recaptcha_v2(site_key, page_url)
print(f"Token: {token[:50]}...")

Submitting the Token

Once you have the g-recaptcha-response token, inject it into the form:

import requests

session = requests.Session()

# Submit form with the solved CAPTCHA token
response = session.post("https://example.com/login", data={
    "username": "user@example.com",
    "password": "password123",
    "g-recaptcha-response": token
}, headers={
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                   "AppleWebKit/537.36 Chrome/122.0.0.0 Safari/537.36",
    "Referer": "https://example.com/login",
    "Origin": "https://example.com"
})

print(response.status_code)

Solving reCAPTCHA v3

reCAPTCHA v3 is trickier because solving services need to produce a high score:

def solve_recaptcha_v3(site_key, page_url, action="submit", min_score=0.7):
    submit_resp = requests.post("https://2captcha.com/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": site_key,
        "pageurl": page_url,
        "version": "v3",
        "action": action,
        "min_score": min_score,
        "json": 1
    }).json()

    if submit_resp["status"] != 1:
        raise Exception(f"Submit failed: {submit_resp}")

    task_id = submit_resp["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://2captcha.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1
        }).json()

        if result["status"] == 1:
            return result["request"]
        elif result["request"] != "CAPCHA_NOT_READY":
            raise Exception(f"Solve error: {result}")

    raise TimeoutError("v3 solving timed out")

Note: v3 solving is less reliable because the score depends on many factors the solving service can’t control.

Method 2: Browser Automation

Using a real browser with anti-detection measures can sometimes bypass reCAPTCHA without solving it — especially v3, which relies on behavioral signals.

Playwright with Human-Like Behavior

from playwright.sync_api import sync_playwright
import time
import random

def human_like_scrape(url):
    with sync_playwright() as p:
        browser = p.chromium.launch(
            headless=False,
            args=["--disable-blink-features=AutomationControlled"]
        )

        context = browser.new_context(
            viewport={"width": 1920, "height": 1080},
            user_agent=(
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                "AppleWebKit/537.36 (KHTML, like Gecko) "
                "Chrome/122.0.0.0 Safari/537.36"
            ),
            locale="en-US",
        )

        context.add_init_script("""
            Object.defineProperty(navigator, 'webdriver', {
                get: () => undefined
            });
        """)

        page = context.new_page()
        page.goto(url, wait_until="networkidle")

        # Simulate human behavior before interacting
        # Move mouse randomly
        for _ in range(3):
            x = random.randint(100, 800)
            y = random.randint(100, 600)
            page.mouse.move(x, y)
            time.sleep(random.uniform(0.2, 0.5))

        # Scroll naturally
        page.mouse.wheel(0, random.randint(200, 500))
        time.sleep(random.uniform(1, 2))

        # If reCAPTCHA v2 checkbox is present
        recaptcha_frame = page.frame_locator(
            'iframe[src*="recaptcha/api2/anchor"]'
        )
        checkbox = recaptcha_frame.locator("#recaptcha-anchor")

        if checkbox.is_visible():
            # Human-like delay before clicking
            time.sleep(random.uniform(0.5, 1.5))
            checkbox.click()

            # Wait for result
            time.sleep(5)

            # Check if image challenge appeared
            challenge_frame = page.frame_locator(
                'iframe[src*="recaptcha/api2/bframe"]'
            )
            if challenge_frame.locator(".rc-imageselect").is_visible():
                print("Image challenge appeared - need solving service")
            else:
                print("Passed without challenge!")

        content = page.content()
        browser.close()
        return content

html = human_like_scrape("https://example.com/search")

Combining Browser + Solving Service

The most robust approach: use browser automation for the environment and a solving service for the challenge:

from playwright.sync_api import sync_playwright
import requests as req
import time

def solve_recaptcha_in_browser(page, api_key):
    """Detect and solve reCAPTCHA within a Playwright page."""

    # Extract site key
    site_key = page.evaluate("""
        () => {
            const el = document.querySelector('.g-recaptcha');
            return el ? el.getAttribute('data-sitekey') : null;
        }
    """)

    if not site_key:
        print("No reCAPTCHA found")
        return True

    page_url = page.url
    print(f"reCAPTCHA detected. Site key: {site_key}")

    # Solve via 2Captcha
    token = solve_recaptcha_v2(site_key, page_url)

    # Inject token into the page
    page.evaluate(f"""
        (token) => {{
            document.getElementById('g-recaptcha-response').innerHTML = token;
        }}
    """, token)

    return True

Method 3: Avoiding reCAPTCHA Entirely

Often the best strategy is to avoid triggering reCAPTCHA in the first place.

Use APIs Instead

Many sites that show reCAPTCHA on their web interface have APIs or mobile endpoints without CAPTCHA protection:

# Instead of scraping the web search page
# Use the site's API if available
response = requests.get("https://example.com/api/v1/search", params={
    "q": "proxy providers",
    "page": 1
}, headers={
    "Authorization": "Bearer your_api_key",
    "User-Agent": "MyApp/1.0"
})

Mobile User Agents

Some sites serve lighter protection to mobile visitors:

mobile_ua = (
    "Mozilla/5.0 (Linux; Android 14; Pixel 8) "
    "AppleWebKit/537.36 (KHTML, like Gecko) "
    "Chrome/122.0.0.0 Mobile Safari/537.36"
)

response = session.get(url, headers={"User-Agent": mobile_ua})

Residential Proxies

Sites often only enable reCAPTCHA for suspicious IPs. Residential proxies from real ISPs bypass IP-based CAPTCHA triggering:

from curl_cffi import requests

session = requests.Session(impersonate="chrome120")
session.proxies = {
    "http": "http://user:pass@residential.example.com:7777",
    "https": "http://user:pass@residential.example.com:7777"
}

# Residential IP = less likely to see reCAPTCHA
response = session.get("https://target-site.com/search?q=data")

reCAPTCHA Bypass Cost Comparison

MethodCost per 1K SolvesSpeedReliability
2Captcha (v2)$2.9915-45sHigh
Anti-Captcha (v2)$2.0010-30sHigh
CapSolver (v2)$1.505-15sMedium-High
Browser automation (v3)Infrastructure onlyInstantMedium
Residential proxies (avoidance)Proxy cost onlyN/AVaries

Handling reCAPTCHA Enterprise

reCAPTCHA Enterprise is harder because it includes:

  • Action-specific scoring
  • Session-level risk analysis
  • Bot behavior fingerprinting beyond the CAPTCHA widget

Solving services support Enterprise but at higher costs ($5-10 per 1K). The most effective approach is combining:

  1. Browser fingerprint management to avoid triggering challenges
  2. Residential proxies for clean IP reputation
  3. Human-like browser behavior
  4. Solving services as a fallback

FAQ

Is bypassing reCAPTCHA legal?

The legality depends on your jurisdiction and the terms of service of the website. Scraping publicly available data is generally legal in many jurisdictions (see hiQ v. LinkedIn), but circumventing security measures may have different legal implications. Always consult legal advice for your specific use case and ensure compliance with the website’s ToS.

Why does reCAPTCHA v3 keep giving me low scores?

reCAPTCHA v3 scores are based on: IP reputation, browser fingerprint consistency, mouse and keyboard patterns, browsing history (Google cookies), and page interaction. Datacenter IPs, headless browsers, and lack of mouse movement all lower your score. Use residential proxies and real browser automation with human-like behavior to improve scores.

Can I solve reCAPTCHA for free?

There’s no reliable free method. Open-source audio transcription (using speech-to-text on the audio challenge) worked in the past but Google has made this much harder. CAPTCHA solving services are the most cost-effective option at $1.50-3.00 per 1,000 solves.

How do I find the reCAPTCHA site key?

Search the page HTML for data-sitekey in the reCAPTCHA div element, or look for render=SITE_KEY in the Google reCAPTCHA script URL. In JavaScript, run: document.querySelector('.g-recaptcha')?.getAttribute('data-sitekey').

Does rotating IPs help with reCAPTCHA?

Yes. reCAPTCHA heavily weighs IP reputation. Rotating residential proxies reduce the chance of being served challenges. However, rotating too frequently can itself be a signal — use sticky sessions of 5-10 minutes per IP for best results.

Conclusion

Bypassing reCAPTCHA in 2026 is a multi-layered challenge. For v2, CAPTCHA solving services remain the most reliable option. For v3, the focus should be on appearing human through proper browser automation, residential proxies, and behavioral signals. In all cases, the best strategy is minimizing how often you encounter reCAPTCHA rather than solving it after the fact.

Useful Resources


Related Reading

Scroll to Top