Sayfa ilk yüklendiğinde tüm CAPTCHA'lar mevcut değildir. Birçok site, CAPTCHA'ları bir düğme tıklaması, form odağı, kaydırma veya zamanlayıcı sonrasında yavaş bir şekilde oluşturur. Otomasyonunuz sayfa kaynağını hemen yakalarsa, CAPTCHA henüz orada değildir. Bu kılavuz, dinamik olarak yüklenen CAPTCHA'ların nasıl algılanacağını ve bekleneceğini kapsar.
Yaygın geç yükleme tetikleyicileri
| Tetikleyici | Örnek | Nasıl etkinleştirilir |
|---|---|---|
| Düğme tıklaması | "Gönder" forma reCAPTCHA'yı ekler | İlk önce düğmeye tıklayın |
| Form odağı | CAPTCHA, girişe odaklanıldığında görünür | Email/password alanına odaklanın |
| Kaydırma konumu | CAPTCHA, bölüm görünür olduğunda yüklenir | Forma ilerleyin |
| Zamanlayıcı | CAPTCHA 3 saniye sonra yükleniyor | Gecikmeyi bekleyin |
| JavaScript koşulu | CAPTCHA, AJAX yanıtından sonra yükleniyor | Önkoşul isteğini tetikleyin |
Yöntem 1: MutationObserver
Eklenen CAPTCHA öğeleri için DOM'u izleyin:
Puppeteer
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://staging.example.com/qa-login');
// Set up MutationObserver before triggering the CAPTCHA
const captchaInfo = await page.evaluate(() => {
return new Promise((resolve) => {
// Check if already present
const existing = document.querySelector('.g-recaptcha, .cf-turnstile, .h-captcha');
if (existing) {
resolve({
type: existing.className,
sitekey: existing.getAttribute('data-sitekey'),
});
return;
}
// Watch for new elements
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeType !== 1) continue;
const captcha = node.matches?.('.g-recaptcha, .cf-turnstile, .h-captcha')
? node
: node.querySelector?.('.g-recaptcha, .cf-turnstile, .h-captcha');
if (captcha) {
observer.disconnect();
resolve({
type: captcha.className,
sitekey: captcha.getAttribute('data-sitekey'),
});
return;
}
}
}
});
observer.observe(document.body, { childList: true, subtree: true });
// Timeout after 30 seconds
setTimeout(() => {
observer.disconnect();
resolve(null);
}, 30000);
});
});
console.log('Detected CAPTCHA:', captchaInfo);
Yükün tetiklenmesi
// Click the submit button to trigger CAPTCHA
await page.click('#submit-btn');
// Or focus the input
await page.focus('#email');
// Or scroll to the form
await page.evaluate(() => {
document.querySelector('#signup-form').scrollIntoView();
});
Yöntem 2: Komut dosyası enjeksiyonunu bekleyin
CAPTCHA'lar kendi JavaScript kitaplıklarını gerektirir. Şuna dikkat edin:
// Wait for reCAPTCHA script to load
await page.waitForFunction(() => {
return typeof window.grecaptcha !== 'undefined'
&& typeof window.grecaptcha.render === 'function';
}, { timeout: 30000 });
// Now extract parameters
const sitekey = await page.evaluate(() => {
const el = document.querySelector('.g-recaptcha');
return el?.getAttribute('data-sitekey');
});
Turnstile için
await page.waitForFunction(() => {
return typeof window.turnstile !== 'undefined';
}, { timeout: 30000 });
const sitekey = await page.evaluate(() => {
const el = document.querySelector('.cf-turnstile');
return el?.getAttribute('data-sitekey');
});
Yöntem 3: İşleme çağrılarını engelleme
Oluşturulmadan önce CAPTCHA kütüphanesine bağlanın:
// Inject before page scripts run
await page.evaluateOnNewDocument(() => {
window.__captchaDetected = null;
// Hook grecaptcha.render
let _grecaptcha;
Object.defineProperty(window, 'grecaptcha', {
set(val) {
_grecaptcha = val;
const origRender = val.render;
val.render = function(container, params) {
window.__captchaDetected = {
type: 'recaptcha',
sitekey: params.sitekey,
callback: params.callback?.name,
container: typeof container === 'string' ? container : container.id,
};
return origRender.apply(this, arguments);
};
},
get() { return _grecaptcha; },
});
});
await page.goto('https://example.com/signup');
// Trigger the CAPTCHA (click, scroll, etc.)
await page.click('#show-form');
// Wait for detection
await page.waitForFunction(() => window.__captchaDetected !== null, {
timeout: 30000,
});
const detected = await page.evaluate(() => window.__captchaDetected);
console.log('Detected:', detected);
// { type: 'recaptcha', sitekey: '6Le-wvkS...', callback: 'onCaptcha', container: 'recaptcha-box' }
Python (Selenium): Tembel CAPTCHA'lar bekleniyor
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")
# Trigger the CAPTCHA loading
submit = driver.find_element(By.ID, "submit-btn")
submit.click()
# Wait for CAPTCHA to appear
try:
captcha_el = WebDriverWait(driver, 30).until(
EC.presence_of_element_located((
By.CSS_SELECTOR,
".g-recaptcha, .cf-turnstile, .h-captcha"
))
)
sitekey = captcha_el.get_attribute("data-sitekey")
captcha_class = captcha_el.get_attribute("class")
if "g-recaptcha" in captcha_class:
captcha_type = "recaptcha"
elif "cf-turnstile" in captcha_class:
captcha_type = "turnstile"
else:
captcha_type = "hcaptcha"
print(f"Type: {captcha_type}, Sitekey: {sitekey}")
except Exception:
print("No CAPTCHA appeared within 30 seconds")
iframe bekleniyor (reCAPTCHA)
# reCAPTCHA loads an iframe even when the div exists but the script is still loading
WebDriverWait(driver, 30).until(
EC.presence_of_element_located((
By.CSS_SELECTOR,
"iframe[src*='recaptcha'], iframe[src*='challenges.cloudflare.com']"
))
)
print("CAPTCHA iframe loaded")
Tam algılama + akışı çözme
import requests
import time
def detect_and_solve(driver, api_key, trigger_action=None):
"""Detect a lazy-loaded CAPTCHA, solve it, and inject the token."""
# 1. Trigger the CAPTCHA
if trigger_action:
trigger_action(driver)
# 2. Wait for it to appear
captcha_el = WebDriverWait(driver, 30).until(
EC.presence_of_element_located((
By.CSS_SELECTOR,
".g-recaptcha, .cf-turnstile, .h-captcha"
))
)
sitekey = captcha_el.get_attribute("data-sitekey")
page_url = driver.current_url
captcha_class = captcha_el.get_attribute("class")
# 3. Determine type and method
if "g-recaptcha" in captcha_class:
method, key_param, token_field = "userrecaptcha", "googlekey", "g-recaptcha-response"
elif "cf-turnstile" in captcha_class:
method, key_param, token_field = "turnstile", "sitekey", "cf-turnstile-response"
else:
method, key_param, token_field = "hcaptcha", "sitekey", "h-captcha-response"
# 4. Solve with CaptchaAI
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": api_key, "method": method,
key_param: sitekey, "pageurl": page_url, "json": "1",
}).json()
task_id = resp["request"]
for _ in range(24):
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["status"] == 1:
token = result["request"]
break
# 5. Inject
driver.execute_script(f"""
const el = document.querySelector('textarea[name="{token_field}"], input[name="{token_field}"]');
if (el) el.value = arguments[0];
""", token)
return token
Sorun giderme
| Sorun | Sebep | Düzeltme |
|---|---|---|
| CAPTCHA hiçbir zaman görünmüyor | Yanlış tetikleme eylemi | CAPTCHA'yı neyin tetiklediğini bulmak için sayfayı inceleyin |
| Site anahtarı boş | Öğe mevcut ancak komut dosyası çalışmadı | Yalnızca div'i değil, CAPTCHA iframe'ini bekleyin |
| Gözlemci bunu özlüyor | CAPTCHA zaten oradaydı | Gözlemciyi kurmadan önce mevcut öğeleri kontrol edin |
| Zaman aşımı | CAPTCHA yalnızca gerçek kullanıcılar için yüklenir | Gerçekçi parmak iziyle tam işlevli bir tarayıcı kullanın |
SSS
Bir CAPTCHA'nın tembel yüklü olup olmadığını nasıl anlarım?
Sayfa kaynağını görüntüleyin (Ctrl+U). CAPTCHA div veya betiği orada değilse ancak sayfayla etkileşimde bulunduğunuzda görünüyorsa, geç yüklenmiştir.
Bu, headless tarayıcılarda çalışır mı?
Evet, uyarılarla birlikte. Bazı siteler yalnızca başlıksız olmayan tarayıcılar için CAPTCHA'lar yükler. Puppeteer veya gizli eklentilerde headless: 'new' kullanın.
Herhangi bir CAPTCHA'yı CaptchaAI ile çözün
API anahtarınızı şu adresten alın:captchaai.com.