Bazı sayfalar iki veya daha fazla CAPTCHA oluşturur (reCAPTCHA'lı bir giriş formu ve ikinci bir reCAPTCHA'lı bir haber bülteni kaydı veya her adımın kendi zorluğunu tetiklediği çok adımlı bir form. Her CAPTCHA'nın benzersiz bir site anahtarı ve hedef öğesi vardır, bu nedenle hepsini tespit etmeniz, bunları paralel olarak çözmeniz ve her jetonu doğru geri çağırmaya yerleştirmeniz gerekir.
Birden fazla CAPTCHA'yı algılama
Selenyumlu Python
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com/multi-captcha-page")
# Find all reCAPTCHA iframes
captcha_iframes = driver.find_elements(
By.CSS_SELECTOR, 'iframe[src*="recaptcha/api2/anchor"]'
)
# Extract sitekeys from each iframe's src
import re
captchas = []
for i, iframe in enumerate(captcha_iframes):
src = iframe.get_attribute("src")
match = re.search(r"k=([A-Za-z0-9_-]+)", src)
if match:
captchas.append({
"index": i,
"sitekey": match.group(1),
"iframe": iframe
})
print(f"Found {len(captchas)} CAPTCHAs on page")
for c in captchas:
print(f" [{c['index']}] sitekey: {c['sitekey']}")
Beklenen çıktı:
Found 2 CAPTCHAs on page
[0] sitekey: 6LcXyzABCDEF-login
[1] sitekey: 6LcAbcDEFGHI-signup
Puppeteer ile JavaScript
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://example.com/multi-captcha-page', {
waitUntil: 'networkidle2'
});
// Extract all reCAPTCHA widgets from the page
const captchas = await page.evaluate(() => {
const widgets = document.querySelectorAll('.g-recaptcha');
return Array.from(widgets).map((el, i) => ({
index: i,
sitekey: el.getAttribute('data-sitekey'),
elementId: el.id || `captcha-${i}`,
callbackName: el.getAttribute('data-callback') || null
}));
});
console.log(`Found ${captchas.length} CAPTCHAs`);
captchas.forEach(c => console.log(` [${c.index}] ${c.sitekey}`));
})();
Tüm CAPTCHA'ları paralel olarak çözme
Tüm CAPTCHA'ları tek seferde CaptchaAI'ye gönderin ve her biri çözümlenene kadar anket yapın.
Python
import requests
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
API_KEY = "YOUR_API_KEY"
PAGE_URL = "https://example.com/multi-captcha-page"
def submit_captcha(sitekey):
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": PAGE_URL,
"json": "1"
})
result = resp.json()
if result["status"] != 1:
raise Exception(f"Submit error: {result['request']}")
return result["request"]
def poll_result(task_id, timeout=120):
deadline = time.time() + timeout
while time.time() < deadline:
time.sleep(5)
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": "1"
})
result = resp.json()
if result["status"] == 1:
return result["request"]
if result["request"] != "CAPCHA_NOT_READY":
raise Exception(f"Poll error: {result['request']}")
raise TimeoutError(f"Task {task_id} timed out")
def solve_all(captchas):
# Submit all in parallel
task_ids = {}
with ThreadPoolExecutor(max_workers=len(captchas)) as pool:
futures = {
pool.submit(submit_captcha, c["sitekey"]): c["index"]
for c in captchas
}
for future in as_completed(futures):
idx = futures[future]
task_ids[idx] = future.result()
print(f"[captcha-{idx}] Submitted → task {task_ids[idx]}")
# Poll all in parallel
tokens = {}
with ThreadPoolExecutor(max_workers=len(task_ids)) as pool:
futures = {
pool.submit(poll_result, tid): idx
for idx, tid in task_ids.items()
}
for future in as_completed(futures):
idx = futures[future]
tokens[idx] = future.result()
print(f"[captcha-{idx}] Solved")
return tokens
# Example usage
captchas = [
{"index": 0, "sitekey": "6LcXyzABCDEF-login"},
{"index": 1, "sitekey": "6LcAbcDEFGHI-signup"}
]
tokens = solve_all(captchas)
Beklenen çıktı:
[captcha-0] Submitted → task 71823456
[captcha-1] Submitted → task 71823457
[captcha-1] Solved
[captcha-0] Solved
Belirteçleri doğru widget'a enjekte etme
Her reCAPTCHA widget'ının kendi g-recaptcha-response metin alanı vardır. Birden fazla widget mevcut olduğunda, her bir metin alanı kendi widget konteynerinin içine yerleştirilir.
Python (Selenyum)
def inject_tokens(driver, captchas, tokens):
for c in captchas:
idx = c["index"]
token = tokens[idx]
# Find the textarea within the widget's container
container = driver.find_elements(By.CSS_SELECTOR, ".g-recaptcha")[idx]
textarea = container.find_element(
By.CSS_SELECTOR, 'textarea[name="g-recaptcha-response"]'
)
driver.execute_script(
"arguments[0].value = arguments[1];", textarea, token
)
# Trigger the callback if defined
callback = c.get("callback")
if callback:
driver.execute_script(f"{callback}('{token}');")
print(f"[captcha-{idx}] Token injected")
inject_tokens(driver, captchas, tokens)
JavaScript (Puppeteer)
async function injectTokens(page, captchas, tokens) {
for (const captcha of captchas) {
const token = tokens[captcha.index];
await page.evaluate((idx, tkn, callbackName) => {
const widgets = document.querySelectorAll('.g-recaptcha');
const textarea = widgets[idx].querySelector(
'textarea[name="g-recaptcha-response"]'
);
textarea.value = tkn;
if (callbackName && typeof window[callbackName] === 'function') {
window[callbackName](tkn);
}
}, captcha.index, token, captcha.callbackName);
console.log(`[captcha-${captcha.index}] Token injected`);
}
}
await injectTokens(page, captchas, tokens);
Karışık CAPTCHA türleri
Bir sayfada farklı CAPTCHA türleri varsa (ör. reCAPTCHA + Turnstile), her türü ayrı ayrı algılayın:
def detect_all_captchas(driver):
detected = []
# reCAPTCHA
recaptchas = driver.find_elements(By.CSS_SELECTOR, ".g-recaptcha")
for i, el in enumerate(recaptchas):
detected.append({
"type": "userrecaptcha",
"sitekey": el.get_attribute("data-sitekey"),
"label": f"recaptcha-{i}"
})
# Turnstile
turnstiles = driver.find_elements(By.CSS_SELECTOR, ".cf-turnstile")
for i, el in enumerate(turnstiles):
detected.append({
"type": "turnstile",
"sitekey": el.get_attribute("data-sitekey"),
"label": f"turnstile-{i}"
})
return detected
Her birini eşleşen method parametresiyle gönderin - reCAPTCHA için userrecaptcha, Turnstile için turnstile.
Sorun giderme
| Sorun | Sebep | Düzeltme |
|---|---|---|
| Jeton enjekte edildi ancak form hâlâ engellendi | Geri arama tetiklenmedi | data-callback'yi kontrol edin ve jetonla çağırın |
| Yalnızca ilk CAPTCHA algılandı | İkinci CAPTCHA geç yükleniyor | Taramadan önce tüm iframe'lerin/widgets'nin görünmesini bekleyin |
| Yanlış widget'ta yanlış belirteç | Dizin uyuşmazlığı | Belirteçleri konumsal dizinle değil site anahtarlarıyla eşleyin |
ERROR_WRONG_GOOGLEKEY |
Site anahtarı hatalı şekilde çıkarıldı | Site anahtarını iframe src veya data-sitekey özelliğinden doğrulayın |
SSS
Bir sayfanın her CAPTCHA için farklı site anahtarları olabilir mi?
Evet. Her widget ayrı bir site anahtarı kullanabilir. Bir site anahtarını paylaştıklarını varsaymak yerine her zaman widget başına site anahtarını çıkarın.
Sırayla mı yoksa paralel olarak mı çözmeliyim?
Paralel olarak. Her çözüm 15-30 saniye sürer. İki CAPTCHA'yı paralel olarak çözmek, bir CAPTCHA'yı çözmekle aynı süreyi alır.
Ya ikinci CAPTCHA yalnızca ilk formu gönderdikten sonra görünürse?
Yeni oluşturulan CAPTCHA'ları tespit etmek için her form gönderiminden sonra sayfayı yeniden tarayın. Yeni widget'ı beklemek için WebDriverWait (Selenium) veya page.waitForSelector (Puppeteer) kullanın.
CaptchaAI ile sayfa başına istediğiniz sayıda CAPTCHA'yı çözün
API anahtarınızı şu adresten alın:captchaai.com.