reCAPTCHA v2'yi bir web kazıma (web scraping) iş akışında çözmenin özü tek cümleye sığar: sayfadaki sitekey ile pageurl'i çıkarın, bunları CaptchaAI API'sine gönderin, dönen token'ı sayfanın g-recaptcha-response alanına enjekte edin. Kazıyıcı bu üç hareketi kendisi yaptığında, onay kutusu ya da resim ızgarası akışınızı artık durdurmaz.
İki yol vardır ve seçim hedef siteye göre değişir: tam bir tarayıcı sürdüğünüz senaryo (Selenium veya Puppeteer) ile tarayıcıyı hiç çalıştırmadığınız saf HTTP senaryosu. Aşağıda her ikisi için de çalışan kod var.
reCAPTCHA v2 çözümü kazımada nasıl işler?
Her reCAPTCHA v2 widget'ı, çözüm için yalnızca iki parametreye dayanır:
| Parametre | Ne işe yarar |
|---|---|
googlekey |
Sayfa HTML'ine gömülü genel sitekey |
pageurl |
CAPTCHA'nın göründüğü adres |
Kazıyıcınız bu ikisini CaptchaAI API'sine gönderir, çözülmüş token'ı periyodik sorgulama (polling) ile bekler ve gelen token'ı sayfadaki g-recaptcha-response alanına yazar (ya da callback fonksiyonunu tetikler). Hedef sitenin arka ucu token'ı Google'a doğrulatır ve isteğin geçmesine izin verir. Token tarafınızda üretilmez, yalnızca taşınır — bu yüzden akışın geri kalanı verinin nasıl çekildiğinden bağımsızdır.
Peki hangi yolu seçmelisiniz? Kısa bir karar tablosu:
| Durum | Önerilen yol |
|---|---|
| Sayfa içeriği JavaScript ile yükleniyor (tek sayfa uygulaması) | Tam tarayıcı (Selenium / Puppeteer) |
| Klasik form gönderimi, token POST alanı olarak kabul ediliyor | Tarayıcısız HTTP |
| Emin değilsiniz | Önce HTTP deneyin, token reddedilirse tarayıcıya geçin |
Python ile çözüm: 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()
Kritik nokta beşinci adımdadır: token'ı alana yazmakla yetinmeyin, sayfanın data-callback işlevini de kontrol edin. Tanımlıysa onu tetikleyin, değilse formu doğrudan gönderin — bu ikili kontrol "token geçerli ama site engelliyor" durumlarını büyük ölçüde önler.
Node.js ile çözüm: 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);
Mantık Python sürümüyle aynıdır. Buradaki tek önemli ayrıntı, token enjeksiyonundan sonraki waitForNavigation çağrısıdır: sayfayı erken okuyup boş veri çekmemek için yönlendirmenin bitmesini bekler.
Tarayıcısız yöntem: yalnızca HTTP
Hedef site CAPTCHA'yı bir form gönderimi akışında iletiyorsa tarayıcıyı tamamen devre dışı bırakabilirsiniz. Bu en hafif yoldur: bellek ve CPU maliyeti düşük olduğu için tek makinede çok daha fazla eşzamanlı istek sürebilirsiniz.
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])
Bu yaklaşım yalnızca site, token'ı bir POST alanı olarak kabul ediyorsa çalışır. Sayfa token'ı JavaScript üzerinden bekliyorsa (tek sayfa uygulamaları genelde böyledir) Selenium veya Puppeteer yoluna dönmeniz gerekir.
Headless mod engellenirse ne yapmalı?
Bazı siteler headless tarayıcıları CAPTCHA görünmeden önce tanıyıp engeller. reCAPTCHA'yı hiç göremeden engelleniyorsanız birkaç ayar akışı kurtarır:
- Puppeteer'da
headless: "new"kullanın (daha yeni headless modu). - Chromium işaretlerine yalnızca
--no-sandboxgibi nötr bayraklar ekleyin. - Gerçekçi bir User-Agent dizesi tanımlayın; varsayılan otomasyon dizeleri hızla işaretlenir.
- CaptchaAI çözümlerinizle birlikte proxy yapılandırmanızı gözden geçirin.
Amaç sihir değil: engellenip CAPTCHA'ya hiç ulaşamadığınız durumu, CAPTCHA'nın normal çıktığı bir duruma çevirmek. Gerisini API çözer.
Türkiye'den bir senaryo: e-ticaret QA akışı
Türkiye'deki geliştirici ekiplerinin büyük bölümü e-ticaret ve ödeme entegrasyonlarıyla çalışır. Tipik bir örnek: kendi hazırlık (staging) ortamınızdaki satın alma akışı reCAPTCHA v2 ile korunuyor ve QA testlerinizi gün içinde yüzlerce kez otomatik koşturmak istiyorsunuz. Her koşuda insanın onay kutusuna tıklamasını beklemek testi anlamsız kılar; CAPTCHA'yı API ile çözüp token'ı enjekte ettiğinizde test paketi kesintisiz akar.
Bu senaryoda iki nokta öne çıkar. Birincisi uyumluluk: kazınan veri kişisel bilgi içeriyorsa süreç KVKK kapsamına girer, bu yüzden bu tür otomasyonu yalnızca yetkiniz olan sistemlerde ve kendi verinizle sınırlı tutun. İkincisi maliyet öngörülebilirliği: CaptchaAI thread bazlı ücretlendirir, yani BASIC ($15/ay, 5 thread) gibi sabit bir aylık USD tutarı ödersiniz; TL kuru dalgalansa da bütçeniz çözüm sayısına göre şişmez. Yüksek hacimde daha fazla eşzamanlılık gerekiyorsa STANDARD ($30/ay, 15 thread) veya ADVANCE ($90/ay, 50 thread) planlarına geçmek thread sayısını artırır.
Sık sorulan sorular
Yüksek hacimli kazımada çözüm süresi darboğaz olur mu?
Tek bir çözüm 15–60 saniye sürer. Kazımayı yavaşlatmamak için çözümleri paralel çalıştırın: CaptchaAI thread başına eşzamanlı görev yürütmenize izin verir, dolayısıyla plan thread sayınız kadar CAPTCHA aynı anda çözülebilir.
Token neden geçersiz görünüyor veya doğrulanmıyor?
Genelde iki nedenden: token tek kullanımlıktır ve yaklaşık 2 dakika sonra geçerliliğini yitirir, ya da callback tetiklenmeden yalnızca alan doldurulmuştur. Her istek için taze bir çözüm alın ve enjeksiyondan sonra data-callback işlevini çağırın.
Kazıdığım veriler KVKK kapsamına girer mi?
İçinde kişisel veri varsa evet. Ad, e-posta, telefon gibi alanlar toplanıyorsa süreç Kişisel Verilerin Korunması Kanunu kapsamındadır. Otomasyonu yetkili olduğunuz sistemlerde ve sahibi olduğunuz veriyle sınırlı tutun.
CaptchaAI hangi reCAPTCHA türlerini çözer, hCaptcha dahil mi?
reCAPTCHA tarafında kapsam geniştir:
- reCAPTCHA v2 (normal, görünmez ve callback)
- reCAPTCHA v2 Enterprise
- reCAPTCHA v3 ve reCAPTCHA v3 Enterprise
hCaptcha ve FunCaptcha ise henüz desteklenmiyor; bir akışta bunlar çıkıyorsa CaptchaAI'yi yalnızca reCAPTCHA adımları için konumlandırın.
Site reCAPTCHA v2 Enterprise kullanıyorsa akış değişir mi?
Hayır, yalnızca isteğinize enterprise=1 eklemeniz yeterli; kod yapısı aynı kalır. Ayrıntılar için reCAPTCHA v2 Enterprise'ı API ile çözme rehberine bakın.
reCAPTCHA v2 ile kazımaya başlayın
- API anahtarınızı şu adresten alın: captchaai.com/api.php
- Sitekey'i hedef sayfadan çıkarın
- Çözmek ve enjekte etmek için yukarıdaki kod örneklerini kullanın
- Yüksek hacimli iş akışlarını eşzamanlı çözümlerle ölçeklendirin