Tek sayfalı uygulamalar reCAPTCHA'yı dinamik olarak yükler; widget ilk HTML'de mevcut değildir. Bir React oturum açma formu CAPTCHA'yı yalnızca bileşen bağlandığında işler. Bir Vue ödeme sayfası, kullanıcı "Sipariş Ver'i tıkladıktan sonra reCAPTCHA'yı yükler. Geleneksel sayfa kaynağı kazıma bunları tamamen gözden kaçırır. Dinamik olarak yüklenen reCAPTCHA'ları nasıl tespit edip çözeceğiniz aşağıda açıklanmıştır.
SPA'lar Neden Farklıdır?
| Geleneksel sayfa | SPA |
|---|---|
| İlk HTML'de reCAPTCHA betiği | Rota değişikliğinden sonra eklenen komut dosyası |
| Widget sayfa yüklendiğinde görüntüleniyor | Widget bileşen montajında işleniyor |
| Sayfa kaynağındaki site anahtarı | JavaScript paketindeki site anahtarı |
| Form POST aracılığıyla gönderilir | Form XHR/fetch aracılığıyla gönderilir |
Bir SPA'da reCAPTCHA widget'ı, belirli bir kullanıcı eylemi onu tetikleyene kadar mevcut olmayabilir. Otomasyonunuz widget'ın görünmesini beklemelidir.
reCAPTCHA Widget'ını algılama
Elementi bekleyin
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False)
page = browser.new_page()
page.goto("https://staging.example.com/qa-login")
# SPA may need a click or navigation to trigger reCAPTCHA
page.click("#show-login-form")
# Wait for reCAPTCHA iframe to appear
recaptcha_frame = page.wait_for_selector(
"iframe[src*='recaptcha']",
timeout=15000
)
print("reCAPTCHA detected:", recaptcha_frame.get_attribute("src"))
Site Anahtarını Çıkarın
Site anahtarı bir SPA'da birden fazla konumda olabilir:
# Method 1: From the iframe src
iframe_src = recaptcha_frame.get_attribute("src")
# src contains: ...?k=6LcR_RsTAAAAADge...
import re
match = re.search(r'[?&]k=([^&]+)', iframe_src)
site_key = match.group(1) if match else None
# Method 2: From data-sitekey attribute
site_key = page.eval_on_selector(
"[data-sitekey]",
"el => el.getAttribute('data-sitekey')"
)
# Method 3: From JavaScript bundle (last resort)
site_key = page.evaluate("""
() => {
// Check for grecaptcha render calls
const scripts = document.querySelectorAll('script');
for (const s of scripts) {
const match = s.textContent.match(/sitekey['":\s]+(['"])(6L[^'"]+)\\1/);
if (match) return match[2];
}
return null;
}
""")
reCAPTCHA'yı çözme
Site anahtarını aldıktan sonra CaptchaAI'ye gönderin:
import requests
import time
def solve_recaptcha(site_key, page_url):
# Submit task
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": site_key,
"pageurl": page_url,
"json": 1
})
task_id = resp.json()["request"]
# Poll for result
for _ in range(60):
time.sleep(3)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY",
"action": "get",
"id": task_id,
"json": 1
})
data = result.json()
if data["status"] == 1:
return data["request"]
raise TimeoutError("Solve timed out")
Tokenın SPA'ya enjekte edilmesi
SPA'lar geleneksel formlar sunmaz. Belirteci uygulamanın beklediği yere enjekte etmeniz gerekir.
Yöntem 1: Gizli Metin Alanını Ayarlama
token = solve_recaptcha(site_key, "https://staging.example.com/qa-login")
# Inject into the g-recaptcha-response textarea
page.evaluate(f"""
document.getElementById('g-recaptcha-response').value = '{token}';
""")
# Submit the form
page.click("#login-button")
Yöntem 2: Geri Aramayı Tetikleyin
Birçok SPA reCAPTCHA uygulaması geri çağırma işlevini kullanır:
# Find the callback function name
callback = page.evaluate("""
() => {
const widget = document.querySelector('.g-recaptcha');
return widget?.getAttribute('data-callback') || null;
}
""")
# Call it with the token
if callback:
page.evaluate(f"window['{callback}']('{token}')")
else:
# Try the default grecaptcha callback
page.evaluate(f"""
if (window.grecaptcha) {{
// Set the response and trigger verification
document.getElementById('g-recaptcha-response').value = '{token}';
// Find and call any registered callbacks
const form = document.querySelector('form');
if (form) form.dispatchEvent(new Event('submit'));
}}
""")
Yöntem 3: XHR'yi Durdurun (JavaScript / Puppeteer)
const puppeteer = require('puppeteer');
async function solveRecaptchaInSPA() {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
// Intercept the API call and inject the token
await page.setRequestInterception(true);
page.on('request', request => {
if (request.url().includes('/api/login')) {
const postData = JSON.parse(request.postData() || '{}');
// Token already set via page.evaluate — let it pass
request.continue();
} else {
request.continue();
}
});
await page.goto('https://staging.example.com/qa-login');
await page.waitForSelector('[data-sitekey]');
const siteKey = await page.$eval(
'[data-sitekey]',
el => el.getAttribute('data-sitekey')
);
// Solve with CaptchaAI (implementation omitted — same as Python)
const token = await solveCaptcha(siteKey, page.url());
// Inject token and trigger callback
await page.evaluate((t) => {
document.getElementById('g-recaptcha-response').value = t;
const callback = document.querySelector('.g-recaptcha')
?.getAttribute('data-callback');
if (callback && window[callback]) {
window[callback](t);
}
}, token);
}
Çerçeveye Özel Desenler
Tepki (tepki-google-recaptcha)
React uygulamaları genellikle react-google-recaptcha paketini kullanır. Bileşen eşzamansız olarak işlenir:
# Wait for React to mount the component
page.wait_for_selector(".g-recaptcha", state="attached")
# The sitekey is in the rendered div's data attribute
site_key = page.eval_on_selector(
".g-recaptcha", "el => el.dataset.sitekey"
)
Vue (vue-recaptcha)
# Vue may use v-if to conditionally render
# Navigate or interact to trigger the condition
page.click("#proceed-to-checkout")
page.wait_for_selector("iframe[src*='recaptcha']")
Açısal
# Angular apps may lazy-load reCAPTCHA modules
# Wait for the specific Angular component
page.wait_for_selector("re-captcha, app-recaptcha, [data-sitekey]")
Rota Değişikliklerini Ele Alma
SPA'lar sayfayı yeniden kullanır; gezinme, tam yeniden yükleme olmadan gerçekleşir:
# Listen for reCAPTCHA appearing after SPA navigation
page.goto("https://example.com")
# Navigate within the SPA
page.click("a[href='/login']")
# The URL changed but no page reload happened
# Wait for the CAPTCHA to render in the new "page"
page.wait_for_selector("iframe[src*='recaptcha']", timeout=10000)
Sorun giderme
| Sorun | Sebep | Düzeltme |
|---|---|---|
g-recaptcha-response metin alanı bulunamadı |
SPA henüz widget'ı oluşturmadı | wait_for_selector'yi yeterli zaman aşımı ile kullanın |
| Jeton enjekte edildi ancak form gönderilmiyor | Geri arama tetiklenmedi | data-callback işlevini bulun ve çağırın |
| Site anahtarı sayfa kaynağında değil | JS'de paketlenir veya dinamik olarak yüklenir | Widget'ın oluşturulmasını bekleyin, ardından iframe src'den çıkarın |
| Jeton bir kez çalışır, sonra başarısız olur | SPA bileşeni yeniden oluşturuyor ve jetonu temizliyor | Formu göndermeden hemen önce jetonu enjekte edin |
| Widget, jeton enjeksiyonundan sonra yeniden işleniyor | React/Vue reaktivitesi değeri temizler | Textarea'yi ayarlamak yerine data-callback yaklaşımını kullanın |
SSS
Tarayıcıyı atlayıp SPA reCAPTCHA'larını yalnızca HTTP istekleriyle çözebilir miyim?
Site anahtarını çıkarabilir ve form gönderme API çağrısını çoğaltabilirseniz evet. Birçok SPA formu bir REST API uç noktası aracılığıyla gönderilir; bunu doğrudan belirteçle çağırabilirsiniz. Ancak önce site anahtarını ve API uç noktasını keşfetmek için bir tarayıcıya ihtiyacınız vardır.
Yalnızca belirli kullanıcı işlemlerinde görünen reCAPTCHA'yı nasıl halledebilirim?
Tetikleyici eylemi otomatikleştirin (bir düğmeyi tıklayın, bir formu doldurun, bir rotaya gidin), ardından reCAPTCHA öğesinin görünmesini bekleyin. wait_for_selector'yi makul bir zaman aşımı süresiyle kullanın.
CaptchaAI, reCAPTCHA'nın bir SPA'da olup olmadığını önemsiyor mu?
Hayır. CaptchaAI yalnızca site anahtarına ve sayfa URL'sine ihtiyaç duyar. Widget'ın sayfada nasıl yüklendiği, çözümü etkilemez.
İlgili Makaleler
- Api Kullanarak Recaptcha V2 Geri Arama Sorunu Nasıl Çözülür?
- Recaptcha V2 Turnstilesi Aynı Sahada İşleme
- Recaptcha V2 Geri Arama Mekanizması
Sonraki Adımlar
Herhangi bir SPA'da dinamik olarak yüklenen reCAPTCHA'ları çözün -CaptchaAI API anahtarınızı alın.