Penjelasan Mendalam

Cara Menangani reCAPTCHA v2 di Alur Kerja Web Scraping

Saat scraper Anda mencapai reCAPTCHA v2 challenge, alur kerja berhenti. Halaman menunggu manusia menyelesaikan checkbox atau image grid sebelum menyajikan data yang Anda butuhkan. Cara respons kompetitif untuk melanjutkan adalah merutekan CAPTCHA ke solving API: ekstrak sitekey dan URL halaman, kirim ke CaptchaAI, terima token yang valid, dan inject kembali ke halaman.

Panduan ini menunjukkan alur lengkap dengan kode untuk Python (Selenium + requests) dan Node.js (Puppeteer).


Cara Kerja Alur

Setiap widget reCAPTCHA v2 memiliki dua parameter yang dibutuhkan scraper Anda:

  1. googlekey — sitekey publik yang tertanam di HTML halaman
  2. pageurl — URL tempat CAPTCHA muncul

Scraper Anda mengirim ini ke API CaptchaAI, menunggu token, lalu inject token ke field g-recaptcha-response halaman (atau memanggil callback function). Backend situs target memverifikasi token terhadap Google dan mengizinkan request lewat.


Python: Selenium + CaptchaAI

import requests
import time
from selenium import webdriver
from selenium.webdriver.common.by import By

# Step 1: Open the page with Selenium
driver = webdriver.Chrome()
driver.get("https://example.com/protected-page")

# Step 2: Extract the sitekey
sitekey = driver.find_element(By.CSS_SELECTOR, ".g-recaptcha").get_attribute("data-sitekey")
page_url = driver.current_url

# Step 3: Submit to CaptchaAI
response = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY",
    "method": "userrecaptcha",
    "googlekey": sitekey,
    "pageurl": page_url,
    "json": 1
}).json()

task_id = response["request"]

# Step 4: Poll for result
token = None
for _ in range(40):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY",
        "action": "get",
        "id": task_id,
        "json": 1
    }).json()

    if result.get("status") == 1:
        token = result["request"]
        break
    if result.get("request") != "CAPCHA_NOT_READY":
        raise RuntimeError(f"Solve failed: {result['request']}")

# Step 5: Inject the token and submit
driver.execute_script(
    f'document.getElementById("g-recaptcha-response").innerHTML = "{token}";'
)

# Check for callback
callback = driver.execute_script(
    'var el = document.querySelector(".g-recaptcha"); '
    'return el ? el.getAttribute("data-callback") : null;'
)
if callback:
    driver.execute_script(f'{callback}("{token}");')
else:
    driver.find_element(By.CSS_SELECTOR, "form").submit()

# Step 6: Scrape the data
print(driver.page_source[:500])
driver.quit()

Node.js: Puppeteer + CaptchaAI

const puppeteer = require("puppeteer");

async function scrapeWithCaptcha(url) {
  const browser = await puppeteer.launch({ headless: "new" });
  const page = await browser.newPage();
  await page.goto(url, { waitUntil: "networkidle2" });

  // Extract sitekey
  const sitekey = await page.$eval(".g-recaptcha", (el) => el.dataset.sitekey);

  // Submit to CaptchaAI
  const submitRes = await fetch(
    `https://ocr.captchaai.com/in.php?${new URLSearchParams({
      key: "YOUR_API_KEY",
      method: "userrecaptcha",
      googlekey: sitekey,
      pageurl: url,
      json: 1,
    })}`
  );
  const { request: taskId } = await submitRes.json();

  // Poll for result
  let token;
  for (let i = 0; i < 40; i++) {
    await new Promise((r) => setTimeout(r, 5000));
    const res = await fetch(
      `https://ocr.captchaai.com/res.php?${new URLSearchParams({
        key: "YOUR_API_KEY",
        action: "get",
        id: taskId,
        json: 1,
      })}`
    );
    const data = await res.json();
    if (data.status === 1) {
      token = data.request;
      break;
    }
    if (data.request !== "CAPCHA_NOT_READY")
      throw new Error(`Solve failed: ${data.request}`);
  }

  // Inject token
  await page.evaluate((t) => {
    document.getElementById("g-recaptcha-response").innerHTML = t;
    const cb = document.querySelector(".g-recaptcha")?.dataset.callback;
    if (cb && window[cb]) window[cb](t);
  }, token);

  // Wait for navigation after form submit
  await page.waitForNavigation({ waitUntil: "networkidle2" });
  const content = await page.content();
  await browser.close();
  return content;
}

scrapeWithCaptcha("https://example.com/protected-page").then(console.log);

Mode Headless vs Headed

Beberapa situs mendeteksi headless browser dan memblokirnya bahkan sebelum CAPTCHA muncul. Jika Anda diblokir sebelum melihat reCAPTCHA:

  • Gunakan headless: "new" di Puppeteer (mode standar yang lebih baru)
  • Tambahkan `` ke flag Chromium
  • Gunakan string User-Agent yang nyata
  • Pertimbangkan menggunakan rotasi egress jaringan yang diotorisasi dengan CaptchaAI

Pendekatan HTTP Saja (Tanpa Browser)

Jika situs target menerima CAPTCHA dalam alur form submission, Anda bisa melewati browser sepenuhnya:

import requests
import time

session = requests.Session()
session.headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0"

# Load the page to get cookies
session.get("https://example.com/protected-page")

# Solve the CAPTCHA
sitekey = "6Le-wvkSAAAAAN..."  # extracted from page HTML
solve_resp = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": "YOUR_API_KEY", "method": "userrecaptcha",
    "googlekey": sitekey, "pageurl": "https://example.com/protected-page",
    "json": 1
}).json()

task_id = solve_resp["request"]
time.sleep(15)

# Poll
for _ in range(30):
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": "YOUR_API_KEY", "action": "get", "id": task_id, "json": 1
    }).json()
    if result.get("status") == 1:
        token = result["request"]
        break
    time.sleep(5)

# Submit with token
resp = session.post("https://example.com/protected-page", data={
    "g-recaptcha-response": token,
    "other_field": "value"
})
print(resp.text[:500])

Pertanyaan Umum

Apakah solve reCAPTCHA v2 memperlambat scraper saya?

Setiap solve membutuhkan 15–60 detik. Untuk scraping volume tinggi, jalankan beberapa solve secara paralel (CaptchaAI mendukung concurrent task).

Bisakah saya cache token reCAPTCHA?

Tidak. Setiap token sekali pakai dan expired setelah ~2 menit. Anda memerlukan solve baru untuk setiap request halaman yang dilindungi.

Apakah saya memerlukan browser untuk menangani reCAPTCHA v2?

Tidak selalu. Jika situs menerima g-recaptcha-response sebagai POST field, Anda bisa menggunakan pendekatan HTTP saja. Jika situs memerlukan JavaScript-based pengaturan token, Anda memerlukan browser.

Bagaimana cara menangani rotasi egress jaringan yang diotorisasi dengan CaptchaAI?

CaptchaAI menyelesaikan CAPTCHA di infrastrukturnya sendiri — Anda tidak perlu meneruskan proxy untuk reCAPTCHA v2 standar. Gunakan proxy untuk request scraping berikutnya.

Bagaimana jika situs menggunakan reCAPTCHA Enterprise?

Tambahkan enterprise=1 ke request CaptchaAI Anda. Lihat Cara Solve reCAPTCHA v2 Enterprise via API.


Panduan Terkait

  • Cara Solve reCAPTCHA v2 via API
  • Penanganan CAPTCHA Selenium dengan Python
  • Penanganan CAPTCHA Puppeteer Node.js
  • Error Umum reCAPTCHA v2 Solving
Komentar dinonaktifkan untuk artikel ini.