Perbandingan

WebDriver vs Chrome DevTools Protocol untuk Otomatisasi CAPTCHA

Dua protokol mengontrol Chrome untuk otomatisasi: WebDriver (standar W3C, digunakan oleh Selenium) dan Chrome DevTools Protocol (CDP, digunakan oleh Puppeteer/Playwright). Masing-masing memiliki profil deteksi, kemampuan, dan karakteristik penanganan CAPTCHA yang berbeda.


Arsitektur Protokol

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

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

Perbandingan Head-to-Head

Fitur WebDriver CDP
Protokol HTTP+JSON Soket Web
Standar standar W3C Khusus Chrome
Permukaan deteksi Tinggi (sinyal browser otomatis = true) Lebih rendah (dapat ditambal)
Intersepsi jaringan Tidak (membutuhkan Selenium Wire) Bawaan (Fetch, Network)
Evaluasi JavaScript executeScript (dibungkus) Runtime.evaluate (langsung)
Minta modifikasi Tidak Ya
Modifikasi respons Tidak Ya
Overhead koneksi HTTP per perintah WebSocket yang persisten
** Lintas-browser ** Chrome, Firefox, Safari, Edge Chrome/Chromium saja
Potensi standar Rendah (selalu menyetel tanda webdriver) Tinggi (bendera dapat ditambal)

Perbedaan Deteksi

Deteksi WebDriver (Selenium)

// What sites check for Selenium
sinyal browser otomatis                    // true (set by ChromeDriver)
document.$cdc_asdjflasutopfhvcZLmcfl  // ChromeDriver internal variable
window.callSelenium                    // Older Selenium versions
window._selenium                      // Selenium internals
document.__webdriver_evaluate          // WebDriver namespace
# Even with flag removal, ChromeDriver leaves traces
from selenium import webdriver

options = webdriver.ChromeOptions()
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

Deteksi CDP (Puppeteer)

// 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
});

Pemecahan CAPTCHA: Pendekatan WebDriver

# 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()
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()

Pemecahan CAPTCHA: Pendekatan CDP

// Puppeteer (CDP) + CaptchaAI
const puppeteer = require("puppeteer-extra");
const StealthPlugin = require("puppeteer-extra (mode standar)");
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();
})();

Perbandingan Kemampuan untuk Alur Kerja CAPTCHA

Intersepsi Jaringan

# 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: 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 });
});

Modifikasi Respon

// 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 });
  }
});
# WebDriver: Standard cookie API
driver.add_cookie({"name": "session", "value": "abc123"})
cookies = driver.get_cookies()
// 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");

Matriks Keputusan

Skenario Direkomendasikan Mengapa
Pengujian multi-browser WebDriver Dukungan lintas browser
standar maksimal CDP Permukaan deteksi yang lebih rendah
Proses debug jaringan CDP Intersepsi bawaan
Tim tidak terbiasa dengan CDP WebDriver API yang lebih sederhana, lebih banyak dokumen
Scraping skala tinggi CDP Biaya overhead yang lebih rendah per sesi
Integrasi CI/CD WebDriver Dukungan perkakas yang lebih baik
Situs yang banyak CAPTCHA CDP + CaptchaAI Kombo standar + pecahkan
Pengisian formulir sederhana WebDriver + CaptchaAI Lebih mudah untuk diterapkan

Pendekatan Hibrid: WebDriver + CDP

Selenium 4 mendukung perintah CDP melalui BiDi (dua arah):

from selenium import webdriver

driver = webdriver.Chrome()

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

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

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

Tolok Ukur Kinerja

Metrik WebDriver (Selenium) CDP (Puppeteer) CDP (Playwright)
Sesi dimulai ~2,5 detik ~1,5 detik ~1,2 detik
Navigasi halaman ~500ms di atas kepala ~100ms di atas kepala ~80ms di atas kepala
Eksekusi skrip ~200ms per panggilan ~50ms per panggilan ~40ms per panggilan
Memori per sesi ~350 MB ~280 MB ~260 MB
Pemecahan CAPTCHA (CaptchaAI) 15-30an 15-30an 15-30 detik

Waktu penyelesaian CaptchaAI sama — ini merupakan panggilan API yang tidak bergantung pada protokol browser.


Pemecahan masalah

Masalah Perbaikan WebDriver Perbaikan CDP
Terdeteksi sebagai bot excludeSwitches + opsi konfigurasi standar + tambalan
Tidak dapat mencegat permintaan Gunakan Selenium Wire Gunakan Fetch.enable
Eksekusi lambat Kurangi panggilan execute_script Perintah CDP batch
pengaturan token gagal Periksa konteks iframe Gunakan Runtime.evaluate dengan konteks
Ketidakstabilan sesi Perbarui ChromeDriver Periksa koneksi WebSocket

Pertanyaan Umum

Protokol mana yang memberikan tingkat keberhasilan CAPTCHA lebih baik?

Tingkat keberhasilannya sama — CaptchaAI menyelesaikan masalah di sisi server. Protokol hanya mempengaruhi frekuensi deteksi (seberapa sering CAPTCHA muncul).

Bisakah saya menggabungkan WebDriver dan CDP?

Ya. Selenium 4 mengekspos execute_cdp_cmd(). Gunakan WebDriver untuk navigasi dan CDP untuk patch standar.

Apakah Playwright lebih baik dari keduanya?

Penulis naskah menggunakan CDP secara internal tetapi menyediakan API tingkat yang lebih tinggi dengan tunggu otomatis dan penanganan kesalahan yang lebih baik. Ini adalah jalan tengah yang bagus.

Haruskah saya beralih dari Selenium ke Puppeteer agar CAPTCHA berfungsi?

Jika deteksi adalah masalah utama Anda, ya. Jika Anda memerlukan dukungan lintas browser, tetap menggunakan Selenium + CaptchaAI.


Panduan Terkait


Pilih protokol otomatisasi yang tepat untuk alur kerja CAPTCHA Anda —dapatkan kunci CaptchaAI Andadan selesaikan CAPTCHA apa pun protokolnya.

Komentar dinonaktifkan untuk artikel ini.