Comparisons

CAPTCHA Otomasyonu için WebDriver ve Chrome DevTools Protokolü

"Selenium'dan Puppeteer'a geçersek CAPTCHA derdimiz biter mi?" Hayır. Çözüm tarayıcıda değil, sunucu tarafında CaptchaAI API'sinde yapılır. Protokol seçimi yalnızca üç şeyi belirler: doğrulamanın ne sıklıkta çıkacağı, ağ katmanına erişiminiz ve geçişin maliyeti. WebDriver ile CDP'yi (Puppeteer, Playwright) bu eksenlerde karşılaştıralım.


Mimari fark: arada bir köprü var mı?

WebDriver komutları ayrı bir ChromeDriver sürecinden geçer; CDP doğrudan tarayıcıya bağlanır.

WebDriver (Selenium):
  Script ──HTTP──▶ ChromeDriver ──DevTools──▶ Chrome
  (JSON Wire)        (bridge)      (internal)

CDP (Puppeteer/Playwright):
  Script ──WebSocket──▶ Chrome
  (direct)               (no middle layer)

Köprü her komutu bir HTTP turuna çevirir. Fark tek sayfalık testte ölçülmez, yüzlerce sayfalık koşuda süreye ve belleğe yansır.


Algılama yüzeyi: CAPTCHA neden Selenium'da daha sık çıkıyor?

CAPTCHA, tarayıcınız otomasyon olarak sınıflandırıldığında devreye girer.

ChromeDriver'ın geride bıraktığı izler

Siteler şu işaretlere bakar:

// What sites check for Selenium
navigator.userAgent                    // true (set by ChromeDriver)
document.$cdc_asdjflasutopfhvcZLmcfl  // ChromeDriver internal variable
window.callSelenium                    // Older Selenium versions
window._selenium                      // Selenium internals
document.__webdriver_evaluate          // WebDriver namespace

Bilinen bayrakları kapatsanız bile ChromeDriver iç değişkenlerini sayfaya bırakır:

# Even with flag removal, ChromeDriver leaves traces
from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--no-sandbox")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)

driver = webdriver.Chrome(options=options)

# Still detectable via $cdc variables in document

Puppeteer tarafında tablo neden farklı

Puppeteer da bu bayrağı ayarlar, ama sayfa yüklenmeden düzeltilebilir ve $cdc izi kalmaz:

// Puppeteer sets webdriver flag too, but it's fully patchable
await page.evaluateOnNewDocument(() => {
  Object.defineProperty(navigator, 'webdriver', {
    get: () => undefined,
  });
  // No $cdc variables to worry about
  // No Selenium-specific traces
});

Sonuç: CDP'de doğrulama daha seyrek çıkar; çıktığında çözüm iki tarafta da aynıdır.


WebDriver ve CDP: teknik farklar tablosu

Özellik WebDriver CDP
Protokol HTTP + JSON WebSocket
Algılama yüzeyi Yüksek (navigator.webdriver) Düşük (düzeltilebilir)
Ağa müdahale Selenium Wire gerekir Dahili (Fetch, Network)
Çapraz tarayıcı Chrome, Firefox, Safari, Edge Chrome/Chromium

Tek kayıp satır sonuncusu: Firefox ve Safari gerekiyorsa CDP yetmez.


Selenium ile token akışı: sitekey'den forma

Akış iki protokolde de aynı üç adım: sitekey çıkarın, görevi CaptchaAI'ye gönderin, dönen token'ı g-recaptcha-response alanına yazın.

# Selenium (WebDriver) + CaptchaAI
import requests
import time
from selenium import webdriver
from selenium.webdriver.common.by import By

API_KEY = "YOUR_API_KEY"
API_URL = "https://ocr.captchaai.com"

options = webdriver.ChromeOptions()
options.add_argument("--no-sandbox")
driver = webdriver.Chrome(options=options)

driver.get("https://example.com/form")
time.sleep(2)

# Extract sitekey
sitekey = driver.execute_script(
    "return document.querySelector('[data-sitekey]')?.getAttribute('data-sitekey')"
)

# Solve via CaptchaAI
resp = requests.post(f"{API_URL}/in.php", data={
    "key": API_KEY, "method": "userrecaptcha",
    "googlekey": sitekey, "pageurl": driver.current_url, "json": 1,
})
task_id = resp.json()["request"]

for _ in range(60):
    time.sleep(5)
    resp = requests.get(f"{API_URL}/res.php", params={
        "key": API_KEY, "action": "get", "id": task_id, "json": 1,
    })
    data = resp.json()
    if data["request"] != "CAPCHA_NOT_READY":
        break

token = data["request"]

# Inject token
driver.execute_script(f"""
    document.querySelector('#g-recaptcha-response').value = '{token}';
    document.querySelectorAll('[name="g-recaptcha-response"]')
        .forEach(el => {{ el.value = '{token}'; }});
""")

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

Göndermeden önce alanın dolduğunu doğrulayın; yanlış iframe seçimi hata vermeden boş alan bırakır.


Puppeteer ile token akışı: enjeksiyonu alt katmandan yapmak

Aynı üç adımı Runtime.evaluate ile daha alt seviyeden yazarsınız; ağ olaylarını da aynı oturumda dinlersiniz — bu, sorun gidermeyi kısaltır.

// Puppeteer (CDP) + CaptchaAI
const puppeteer = require("puppeteer-extra");
const StealthPlugin = require("puppeteer-extra-plugin-stealth");
const https = require("https");

puppeteer.use(StealthPlugin());

const API_KEY = "YOUR_API_KEY";
const API_URL = "https://ocr.captchaai.com";

function solveCaptcha(siteUrl, sitekey) {
  // Submit + poll (simplified)
  return new Promise(async (resolve, reject) => {
    const submitResp = await httpPost(`${API_URL}/in.php`, {
      key: API_KEY, method: "userrecaptcha",
      googlekey: sitekey, pageurl: siteUrl, json: "1",
    });

    const taskId = submitResp.request;

    for (let i = 0; i < 60; i++) {
      await new Promise((r) => setTimeout(r, 5000));
      const result = await httpGet(
        `${API_URL}/res.php?key=${API_KEY}&action=get&id=${taskId}&json=1`
      );
      if (result.request !== "CAPCHA_NOT_READY") {
        return resolve(result.request);
      }
    }
    reject(new Error("Timeout"));
  });
}

(async () => {
  const browser = await puppeteer.launch({
    headless: "new",
    args: ["--no-sandbox", "--window-size=1920,1080"],
  });

  const page = await browser.newPage();

  // CDP: Enable network interception
  const cdp = await page.createCDPSession();
  await cdp.send("Network.enable");

  // Monitor CAPTCHA-related requests
  cdp.on("Network.requestWillBeSent", (params) => {
    if (params.request.url.includes("recaptcha")) {
      console.log(`CAPTCHA request: ${params.request.url}`);
    }
  });

  await page.goto("https://example.com/form", { waitUntil: "networkidle0" });

  const sitekey = await page.evaluate(() =>
    document.querySelector("[data-sitekey]")?.getAttribute("data-sitekey")
  );

  if (sitekey) {
    const token = await solveCaptcha(page.url(), sitekey);

    // CDP: Inject via Runtime.evaluate (lower-level than page.evaluate)
    await cdp.send("Runtime.evaluate", {
      expression: `
        document.querySelector('#g-recaptcha-response').value = '${token}';
        document.querySelector('form').submit();
      `,
    });
  }

  await browser.close();
})();

Cloudflare Turnstile'da token alanı cf-turnstile-response olur; gönder–sorgula deseni GeeTest v3'te de aynıdır.


Yalnızca CDP'de olan yetenekler

İsteklere müdahale

WebDriver'da yerleşik müdahale API'si yok; Selenium Wire trafiği yerel proxy'den geçirir:

# WebDriver: Cannot intercept requests natively
# Requires selenium-wire (third-party)
from seleniumwire import webdriver

driver = webdriver.Chrome()
# selenium-wire proxies all traffic through a local proxy

CDP'de bu yetenek yerleşiktir:

// CDP: Built-in request interception
await cdp.send("Fetch.enable", {
  patterns: [{ urlPattern: "*recaptcha*" }],
});

cdp.on("Fetch.requestPaused", async ({ requestId, request }) => {
  console.log(`Intercepted: ${request.url}`);
  await cdp.send("Fetch.continueRequest", { requestId });
});

Yanıtı değiştirme

Yapılandırma yanıtını test ortamında değiştirmek yalnızca CDP'de mümkündür:

// CDP: Can modify responses (WebDriver cannot)
cdp.on("Fetch.requestPaused", async ({ requestId, request }) => {
  if (request.url.includes("captcha-config")) {
    // Return modified response
    await cdp.send("Fetch.fulfillRequest", {
      requestId,
      responseCode: 200,
      body: btoa(JSON.stringify({ enabled: false })),
    });
  } else {
    await cdp.send("Fetch.continueRequest", { requestId });
  }
});

httpOnly çerezlere erişim

WebDriver standart çerez API'sini sunar:

# WebDriver: Standard cookie API
driver.add_cookie({"name": "session", "value": "abc123"})
cookies = driver.get_cookies()

CDP httpOnly çerezleri de okur; WebDriver okuyamaz:

// CDP: Full cookie control including httpOnly
await cdp.send("Network.setCookie", {
  name: "session",
  value: "abc123",
  domain: "example.com",
  httpOnly: true,
  secure: true,
});

// Get all cookies including httpOnly (WebDriver can't access these)
const { cookies } = await cdp.send("Network.getAllCookies");

Hibrit yol: Selenium 4 içinden CDP komutları

Seçmek zorunda değilsiniz: Selenium 4 CDP komutlarını doğrudan çalıştırır. Gezinme WebDriver'da kalır, alt seviye çağrılar CDP'ye gider:

from selenium import webdriver

driver = webdriver.Chrome()

# Use WebDriver for navigation
driver.get("https://example.com")

# Use CDP for QA testi patches
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
    "source": """
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined
        });
    """
})

# Use CDP for network events
driver.execute_cdp_cmd("Network.enable", {})

Mevcut test paketini yeniden yazmadan CDP'ye kademeli geçmenin en düşük riskli yolu budur.


Performans: sayılar nerede fark ediyor?

Aşağıdaki değerler gözlemlenen verilere ve kullanıcı raporlarına dayanır. Sonuçlar ortama, hacme ve zamana göre değişebilir.

Metrik WebDriver CDP (Puppeteer/Playwright)
Oturum başlangıcı ~2,5 sn ~1,2–1,5 sn
Script çalıştırma ~200 ms ~40–50 ms
Oturum belleği ~350 MB ~260–280 MB
CAPTCHA çözümü 15–30 sn 15–30 sn

En önemli satır sonuncusu: çözüm süresi protokolden bağımsızdır; üstteki milisaniyeler ancak oturum sayısıyla çarpılınca anlam kazanır.


Hangi iş yükü hangi protokole gider?

Senaryo Önerilen Neden
Firefox ve Safari testi WebDriver Çapraz tarayıcı
Yüksek hacimli web kazıma CDP Düşük ek yük
Mevcut CI/CD hattı WebDriver Olgun ekosistem
CAPTCHA'nın sık çıktığı siteler CDP + CaptchaAI Az iz + API çözümü

Bu kolon kural değil, tartışmanın başlangıç noktasıdır.


İstanbul'dan bir örnek: gece koşan QA hattı

Bir entegratör ekibi ödeme adımını her gece 200 kez test ediyor; reCAPTCHA v2 açık, koşu Europe/Istanbul saatiyle 02.00'de başlıyor. Ekip zaten Selenium'da: 200 oturum × 2,5 sn ≈ 8 dakika ek yük, 40 dakikalık koşuda kararı çevirmez. Asıl CDP'ye taşınacak iş, gündüz koşan 50.000 sayfalık katalog senkronizasyonu.

Fiyatlar USD ve thread tabanlı; kur oynaklığının bütçeyi bozmaması Türkiye'deki ekipler için avantaj. Gece koşusuna BASIC ($15/ay, 5 thread), kataloğa ADVANCE ($90/ay, 50 thread) uyar. Kişisel veri toplanıyorsa iş KVKK kapsamına girer.


Sorun giderme

Sorun WebDriver çözümü CDP çözümü
Bot olarak algılandı excludeSwitches ayarları Test profilini sadeleştirin
Token enjeksiyonu başarısız iframe bağlamını kontrol edin Doğru bağlamla Runtime.evaluate
Token reddedildi 60 saniye içinde gönderin Aynı kural

Sık sorulan sorular

Firefox ve Safari testlerim varsa CDP bir seçenek mi?

Hayır, CDP yalnızca Chrome ve Chromium tabanlı tarayıcılarda çalışır. Çapraz tarayıcı matrisiniz varsa WebDriver'da kalın.

Eşzamanlılığı çözüm sayısı mı, thread sayısı mı belirler?

Thread sayısı. BASIC ($15/ay, 5 thread) aynı anda 5, ADVANCE ($90/ay, 50 thread) aynı anda 50 CAPTCHA demektir.

CaptchaAI hangi CAPTCHA türlerini destekliyor?

reCAPTCHA v2 ve v3, Cloudflare Turnstile, Cloudflare doğrulama akışı, GeeTest v3, görüntü/OCR ve metin tabanlı CAPTCHA'lar; CaptchaFox (beta), Friendly Captcha (beta) ve Lemin (beta). hCaptcha ve FunCaptcha desteklenmiyor, GeeTest v4 için "çok yakında" geçerli.


İlgili rehberler


CaptchaAI API anahtarınızı alın, örneği kopyalayın, ilk token'ınızı bugün üretin.

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