Troubleshooting

reCAPTCHA v2 ve v3'ü Aynı Sayfada Kullanma

Bazı web siteleri hem reCAPTCHA v2'yi hem de v3'ü aynı sayfada uygular. Tipik model şu şekildedir: v3 arka planda görünmez bir şekilde çalışır ve puan çok düşükse v2 görünür bir geri dönüş mücadelesi olarak görünür. Bu ikili uygulama otomasyon açısından kafa karışıklığı yaratır çünkü iki farklı CAPTCHA tipini farklı çözüm yöntemleriyle ele almanız gerekir. Bu kılavuzda tespit, çözüm stratejileri ve sık karşılaşılan uç durumlar ele alınmaktadır.


Siteler neden hem v2 hem de v3'ü birlikte kullanıyor?

User visits page
    ↓
reCAPTCHA v3 runs invisibly in background
    ↓
Score returned to server (e.g., 0.4)
    ↓
Score below threshold (e.g., < 0.7)?
    ├─ YES → Show reCAPTCHA v2 checkbox/image challenge
    └─ NO  → Allow action without visible CAPTCHA

Bu model her iki dünyanın da en iyisini sağlar:

  • Çoğu kullanıcı (yüksek v3 puanı) CAPTCHA → düşük sürtünmenin olmadığını görüyor
  • Şüpheli kullanıcılar (düşük v3 puanı) v2 mücadelesine bakın → güvenlik geri dönüşü
  • Web sitesi operatörü görünmez ve görünür arasındaki eşiği kontrol eder

İkili uygulama modelleri

Model 1: v3 ön değerlendirmesi + v2 geri dönüşü

En yaygın desen. Önce v3 çalışır ve v2 yalnızca gerektiğinde görünür.

<!-- Both scripts loaded -->
<script src="https://www.google.com/recaptcha/api.js?render=V3_SITE_KEY"></script>
<script src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script>

<form id="loginForm">
    <!-- v2 widget (hidden initially) -->
    <div id="recaptcha-v2-container" style="display:none;">
        <div class="g-recaptcha" data-sitekey="V2_SITE_KEY"></div>
    </div>
    <button type="submit">Login</button>
</form>

<script>
// First attempt: v3 invisible
grecaptcha.ready(function() {
    grecaptcha.execute('V3_SITE_KEY', {action: 'login'}).then(function(v3Token) {
        fetch('/api/verify-v3', {
            method: 'POST',
            body: JSON.stringify({token: v3Token})
        })
        .then(r => r.json())
        .then(data => {
            if (data.score < 0.7) {
                // Score too low → show v2 fallback
                document.getElementById('recaptcha-v2-container').style.display = 'block';
                grecaptcha.render('recaptcha-v2-container', {sitekey: 'V2_SITE_KEY'});
            } else {
                // Score OK → submit form directly
                document.getElementById('loginForm').submit();
            }
        });
    });
});
</script>

Model 2: Farklı işlemler için farklı site anahtarları

Bazı siteler pasif izleme için v3'ü ve belirli yüksek riskli eylemler için v2'yi kullanır:

Homepage → v3 only (passive score)
Login page → v3 assessment, v2 fallback
Checkout → v2 always (high security)
Contact form → v3 only

Desen 3: Tek komut dosyası, ikili mod

Google, hem v2 hem de v3'ü işleyen tek bir reCAPTCHA komut dosyasının yüklenmesini destekler:

<script src="https://www.google.com/recaptcha/api.js?render=V3_SITE_KEY"></script>
<script>
    // v3 execute
    grecaptcha.execute('V3_SITE_KEY', {action: 'login'});

    // v2 render (uses a different site key)
    grecaptcha.render('v2-container', {sitekey: 'V2_SITE_KEY'});
</script>

İkili uygulamanın tespiti

Python tespiti

import requests
import re

def detect_dual_recaptcha(url):
    """Detect if a page uses both reCAPTCHA v2 and v3."""
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/120.0.0.0 Safari/537.36",
    }
    html = requests.get(url, headers=headers, timeout=15).text

    result = {
        "has_v3": False,
        "has_v2": False,
        "v3_site_key": None,
        "v2_site_key": None,
        "dual": False,
        "pattern": None,
    }

    # Detect v3 (render parameter or enterprise.execute)
    v3_match = re.search(r"api\.js\?render=([A-Za-z0-9_-]+)", html)
    if v3_match and v3_match.group(1) != "explicit":
        result["has_v3"] = True
        result["v3_site_key"] = v3_match.group(1)

    # Detect v3 in execute calls
    v3_execute = re.search(
        r"grecaptcha\.(?:enterprise\.)?execute\s*\(\s*['\"]([^'\"]+)['\"]",
        html,
    )
    if v3_execute:
        result["has_v3"] = True
        if not result["v3_site_key"]:
            result["v3_site_key"] = v3_execute.group(1)

    # Detect v2 (g-recaptcha class or explicit render)
    v2_match = re.search(r'data-sitekey="([^"]+)"', html)
    if v2_match:
        key = v2_match.group(1)
        if key != result.get("v3_site_key"):
            result["has_v2"] = True
            result["v2_site_key"] = key

    # Check for explicit v2 render
    v2_render = re.search(
        r"grecaptcha\.render\s*\([^,]+,\s*\{[^}]*sitekey:\s*['\"]([^'\"]+)",
        html,
    )
    if v2_render:
        result["has_v2"] = True
        if not result["v2_site_key"]:
            result["v2_site_key"] = v2_render.group(1)

    result["dual"] = result["has_v3"] and result["has_v2"]

    if result["dual"]:
        # Determine pattern
        if "display:none" in html or "display: none" in html:
            result["pattern"] = "v3_pre_assessment_v2_fallback"
        else:
            result["pattern"] = "v2_v3_simultaneous"

    return result

detection = detect_dual_recaptcha("https://staging.example.com/qa-login")
print(detection)

Node.js tespiti

const axios = require("axios");

async function detectDualRecaptcha(url) {
    const { data: html } = await axios.get(url, { timeout: 15000 });

    const result = {
        hasV3: false,
        hasV2: false,
        v3SiteKey: null,
        v2SiteKey: null,
        dual: false,
    };

    // v3 detection
    const v3Match = html.match(/api\.js\?render=([A-Za-z0-9_-]+)/);
    if (v3Match && v3Match[1] !== "explicit") {
        result.hasV3 = true;
        result.v3SiteKey = v3Match[1];
    }

    // v2 detection
    const v2Match = html.match(/data-sitekey="([^"]+)"/);
    if (v2Match && v2Match[1] !== result.v3SiteKey) {
        result.hasV2 = true;
        result.v2SiteKey = v2Match[1];
    }

    result.dual = result.hasV3 && result.hasV2;
    return result;
}

detectDualRecaptcha("https://staging.example.com/qa-login").then(console.log);

Çift reCAPTCHA için strateji çözme

Strateji 1: Önce v3'ü, ardından gerekiyorsa v2'yi çözün

En uygun strateji sitenin kendi akışını yansıtır:

import requests
import time

API_KEY = "YOUR_API_KEY"

def solve_v3(site_key, page_url, action="login"):
    """Solve reCAPTCHA v3 and return token."""
    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": site_key,
        "pageurl": page_url,
        "version": "v3",
        "action": action,
        "json": 1,
    }).json()

    task_id = submit["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id, "json": 1,
        }).json()
        if result.get("status") == 1:
            return result["request"]

    raise TimeoutError("v3 solve timeout")

def solve_v2(site_key, page_url):
    """Solve reCAPTCHA v2 and return token."""
    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": site_key,
        "pageurl": page_url,
        "json": 1,
    }).json()

    task_id = submit["request"]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id, "json": 1,
        }).json()
        if result.get("status") == 1:
            return result["request"]

    raise TimeoutError("v2 solve timeout")

def solve_dual_recaptcha(v3_key, v2_key, page_url, action="login"):
    """Handle dual reCAPTCHA: try v3, fall back to v2."""
    # Step 1: Try v3
    v3_token = solve_v3(v3_key, page_url, action)

    # Step 2: Submit v3 token to target
    response = requests.post(f"{page_url}/verify", data={
        "g-recaptcha-response": v3_token,
    })

    # Step 3: Check if v2 fallback is needed
    if "recaptcha" in response.text.lower() and v2_key:
        print("v3 score too low — v2 fallback triggered")
        v2_token = solve_v2(v2_key, page_url)
        return {"version": "v2", "token": v2_token}

    return {"version": "v3", "token": v3_token}

result = solve_dual_recaptcha(
    v3_key="6LcExample_v3_key",
    v2_key="6LcExample_v2_key",
    page_url="https://staging.example.com/qa-login",
)
print(f"Solved with {result['version']}")

Strateji 2: v3'ü atlayın, v2'yi doğrudan çözün

Sitenin otomatik trafik için her zaman v2 gösterdiğini biliyorsanız (v3 puanı düşük olacaktır), v3'ü atlayın ve v2'yi hemen çözün:

# If you consistently fail v3 assessment, just solve v2 directly
token = solve_v2(v2_site_key, page_url)
submit_form(token)

Bu, eşiği geçemeyebilecek bir v3 çözümünün zamanından ve maliyetinden tasarruf sağlar.

Strateji 3: Tarayıcı tabanlı işleme

Karmaşık uygulamalarda geri dönüş akışını yönetmek için bir tarayıcı kullanın:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time

driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")
time.sleep(3)

# Check if v2 widget is visible
v2_visible = driver.execute_script("""
    const container = document.querySelector('.g-recaptcha');
    if (!container) return false;
    const style = window.getComputedStyle(container.parentElement);
    return style.display !== 'none' && style.visibility !== 'hidden';
""")

if v2_visible:
    # v2 is showing — solve v2
    sitekey = driver.find_element(
        By.CSS_SELECTOR, "[data-sitekey]"
    ).get_attribute("data-sitekey")
    token = solve_v2(sitekey, driver.current_url)
    driver.execute_script(
        f'document.getElementById("g-recaptcha-response").value = "{token}";'
    )
else:
    # v3 only — solve v3
    # Extract v3 key from page source
    v3_key = driver.execute_script(
        "return document.querySelector('script[src*=\"render=\"]')"
        ".src.match(/render=([^&]+)/)[1];"
    )
    token = solve_v3(v3_key, driver.current_url)
    # Inject v3 token into the form
    driver.execute_script(f"""
        const input = document.createElement('input');
        input.type = 'hidden';
        input.name = 'g-recaptcha-response';
        input.value = '{token}';
        document.querySelector('form').appendChild(input);
    """)

driver.find_element(By.CSS_SELECTOR, "form").submit()

Kenar kasaları

Aynı sayfada iki farklı site anahtarı

Çift reCAPTCHA kullanan sitelerde İKİ farklı site anahtarı bulunur; biri v3 için, diğeri v2 için. V3 anahtarı, ?render=KEY komut dosyası URL'sinde ve grecaptcha.execute('KEY', ...)'de görünür. V2 anahtarı, widget div'deki data-sitekey="KEY"'de görünür. Yanlış sürüm için yanlış anahtarın kullanılması geçersiz belirteçler üretecektir.

v2 geri dönüşüyle reCAPTCHA Enterprise

Bazı Kurumsal uygulamalar puanlama için v3 Enterprise'ı, zorluklar için ise v2'yi kullanır:

# Detect and handle Enterprise + v2 combo
if "recaptcha/enterprise.js" in html:
    # Use enterprise parameter for v3
    v3_params = {"enterprise": 1, "version": "v3"}
else:
    v3_params = {"version": "v3"}

Tek sayfada birden fazla form

Bir sayfada birden fazla form varsa (giriş + kayıt), her birinin kendi reCAPTCHA örneği olabilir. Site anahtarını hedeflediğiniz belirli formdan çıkarın:

# Target the login form specifically
login_form = soup.find("form", id="login-form")
widget = login_form.find(attrs={"data-sitekey": True})
sitekey = widget["data-sitekey"]

Sık sorulan sorular

Hem v2 hem de v3'ü aynı sayfada mı çözmem gerekiyor?

Hayır. Genellikle önce v3'ü çözersiniz (otomatik olarak çalışır). v3 puanı sitenin eşiğini geçerse v2 mücadelesi görünmez ve işlem tamamlanır. Yalnızca v3 puanının geri dönüşü tetiklemesi durumunda v2'yi çözmeniz gerekir.

Çift reCAPTCHA için tek bir CaptchaAI API çağrısı kullanabilir miyim?

No. v2 ve v3, farklı site anahtarlarına ve çözüm yöntemlerine sahip ayrı CAPTCHA türleridir. Her biri CaptchaAI'ye kendi API çağrısını gerektirir. Ancak v3, v2'yi tetiklemeden geçerse yalnızca bir arama yapmanız gerekir.

V2 geri dönüşünün tetiklenip tetiklenmediğini nasıl anlarım?

v3 jetonunu gönderdikten sonra sunucunun yanıtını kontrol edin. Yanıt v2 widget HTML'si içeriyorsa veya bir v2 sorgulamasını tetikliyorsa (yönlendirme veya CAPTCHA HTML'li AJAX yanıtı), geri dönüş tetiklendi. Bir tarayıcıda, v3 gönderiminden sonra v2 kapsayıcısının görünür olup olmadığını kontrol edin.

Her sürüm için hangi site anahtarını kullanmalıyım?

V3 site anahtarı komut dosyası URL'sindedir: api.js?render=V3_KEY. v2 site anahtarı widget HTML'sinde bulunur: data-sitekey="V2_KEY". Bunlar her zaman farklı anahtarlardır.


Özet

İkili reCAPTCHA uygulamaları, görünmez ön değerlendirme için v3'ü ve v3 puanı çok düşük olduğunda görünür bir geri dönüş olarak v2'yi kullanır. Oluşturma parametresini (v3) ve widget data-sitekey'i (v2) kontrol ederek her iki sürümü de tespit edin. Optimum otomasyon stratejisi şudur: önce v3'ü çözünCaptchaAI, jetonu gönderin ve v2'yi yalnızca geri dönüş tetiklenirse çözün. Her sürüm, kendi site anahtarına sahip ayrı bir API çağrısı gerektirir.

İlgili Makaleler

  • Recaptcha Tek Sayfa Uygulama Dinamik
  • Api Kullanarak Recaptcha V2 Geri Arama Sorunu Nasıl Çözülür?
  • Recaptcha V2 Turnstilesi Aynı Sahada İşleme
Bu makale için yorumlar devre dışı bırakılmıştır.