Eğitimler

Tek Sayfada Birden Fazla CAPTCHA'yı İşleme

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.


İlgili kılavuzlar

Bu makale için yorumlar devre dışı bırakılmıştır.