Kısa cevap: ızgaranın ekran görüntüsünü alın, talimat metniyle birlikte CaptchaAI'ye gönderin, yanıtta dönen kutucuk numaralarına Puppeteer ile tıklayın. Tarayıcı tarafında görüntü işleme, model eğitimi veya piksel karşılaştırması yapmanız gerekmez — tek yaptığınız bir PNG göndermek ve bir dizi almaktır.
"Trafik ışığı olan tüm kareleri seçin" tipindeki 3×3 ve 4×4 ızgaralar, reCAPTCHA v2 doğrulamasının otomasyonu en sık durduran hâlidir. Aşağıdaki dört adım, Node.js 14+ ve axios ile üretimde çalışan en kısa akıştır.
Akışın tamamı: dört istek, tek tur
| Aşama | Ne yapılır | Nerede çalışır |
|---|---|---|
| Yakalama | Talimat metni + ızgara ekran görüntüsü | Puppeteer, bframe iframe'i |
| Gönderim | in.php uç noktasına multipart/form-data |
CaptchaAI OCR uç noktası |
| Sorgulama | res.php üzerinden periyodik sorgulama |
5 saniyelik aralıklarla |
| Tıklama | Dönen numaralara sırayla tıklama | Puppeteer |
Grid Image, CaptchaAI'de genel kullanıma açık (GA) bir tiptir ve yayımlanan hız tavanı 1 saniyenin altındadır. Pratikte toplam bekleme süresini belirleyen şey çözümün kendisi değil, sizin sorgulama aralığınızdır.
Önkoşullar
| Öğe | Değer |
|---|---|
| CaptchaAI API anahtarı | captchaai.com panelinden alınır |
| Node.js | 14+ |
| Kütüphaneler | axios, puppeteer |
Hesabınız yoksa önce anahtarı alın: CaptchaAI panelinde kayıt sonrası verilen API anahtarı tek bir dizedir ve koddaki YOUR_API_KEY yer tutucusunun yerine geçer. Anahtarı dosyaya gömmek yerine ortam değişkeninde tutun.
Adım 1: İzgarayı ve talimat metnini yakalayın
İki şeye ihtiyacınız var: kullanıcıya gösterilen talimat cümlesi ve ızgaranın kendisi. İkisi de reCAPTCHA'nın bframe iframe'inin içindedir, ana sayfada değildir — bu yüzden önce doğru frame'i seçin, ekran görüntüsünü de o frame üzerinden alın.
const puppeteer = require('puppeteer');
const fs = require('fs');
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com/page-with-recaptcha');
// Switch to the reCAPTCHA challenge iframe
const frames = page.frames();
const challengeFrame = frames.find((f) => f.url().includes('recaptcha/api2/bframe'));
// Get the instruction text
const instruction = await challengeFrame.$eval(
'.rc-imageselect-desc-no-canonical',
(el) => el.textContent.trim()
);
// Screenshot the grid
const grid = await challengeFrame.$('.rc-imageselect-target');
await grid.screenshot({ path: 'grid.png' });
Talimat metnini boş gönderirseniz doğruluk düşer: çözümü belirleyen bilgi, görselin kendisi kadar "neyi seçeceğim" cümlesidir.
Adım 2: Görseli CaptchaAI'ye gönderin
Gönderim, https://ocr.captchaai.com/in.php uç noktasına multipart/form-data olarak yapılır. method alanı post, img_type alanı recaptcha, grid_size alanı da ızgaranın boyutudur.
const axios = require('axios');
const FormData = require('form-data');
const API_KEY = 'YOUR_API_KEY';
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const form = new FormData();
form.append('key', API_KEY);
form.append('method', 'post');
form.append('grid_size', '3x3');
form.append('img_type', 'recaptcha');
form.append('instructions', instruction);
form.append('json', '1');
form.append('file', fs.createReadStream('grid.png'));
const { data: submitData } = await axios.post('https://ocr.captchaai.com/in.php', form, {
headers: form.getHeaders(),
});
if (submitData.status !== 1) throw new Error(submitData.request);
const taskId = submitData.request;
console.log(`Task submitted: ${taskId}`);
json=1 göndermezseniz yanıt OK|... biçiminde düz metin döner ve ayrıştırma kodunuz kırılır. status alanı 1 değilse hata kodu request alanında gelir — bunu sessizce yutmayın, ilk satırda fırlatın.
Adım 3: Sonucu sorgulayın
Görev kimliğini aldıktan sonra res.php uç noktasını periyodik olarak sorgularsınız. İlk sorgulamadan önce beş saniye beklemek gereksiz istek üretmenizi engeller; sonrasında CAPCHA_NOT_READY yanıtı geldiği sürece beklemeye devam edersiniz.
await sleep(5000);
let cellsToClick;
for (let i = 0; i < 30; i++) {
const { data: pollData } = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: API_KEY, action: 'get', id: taskId, json: 1 },
});
if (pollData.status === 1) {
cellsToClick = JSON.parse(pollData.request);
console.log('Click cells:', cellsToClick);
break;
}
if (pollData.request !== 'CAPCHA_NOT_READY') {
throw new Error(pollData.request);
}
await sleep(5000);
}
İki ayrıntıya dikkat edin. Birincisi, bekleme durumunun anahtar sözcüğü API'de tarihsel olarak CAPCHA_NOT_READY biçiminde, eksik harfle yazılır; dizeyi "düzeltirseniz" döngünüz doğrudan hata dalına düşer. İkincisi, 30 turluk üst sınır bir zaman aşımı görevi görür: süre dolduğunda görevi yeniden göndermek, sonsuza kadar sorgulamaktan daha ucuzdur.
Adım 4: Dönen kutucuklara tıklayın
Yanıt, tıklanacak kutucukların numaralarını içeren bir dizidir. Numaralandırma 1'den başlar ve soldan sağa, yukarıdan aşağıya ilerler: 3×3 bir ızgarada 1–3 üst satır, 4–6 orta satır, 7–9 alt satırdır. Koddaki tiles[cellNum - 1] indislemesinin sebebi budur.
const tiles = await challengeFrame.$$('.rc-imageselect-tile');
for (const cellNum of cellsToClick) {
await tiles[cellNum - 1].click();
await sleep(300);
}
// Click verify
await challengeFrame.click('#recaptcha-verify-button');
console.log(`Solved: clicked tiles ${JSON.stringify(cellsToClick)}`);
await browser.close();
Beklenen çıktı:
Click cells: [1, 3, 6, 9]
Solved: clicked tiles [1,3,6,9]
Tıklamalar arasındaki 300 milisaniyelik gecikme kozmetik değildir: reCAPTCHA arayüzü kutucuk seçimini animasyonla işler, arka arkaya gönderilen tıklamalar kaybolabilir.
Yerel senaryo: gece koşan bir satın alma akışı testi
Türkiye'deki ekiplerde en sık gördüğümüz düzen şu: bir e-ticaret ekibi, ödeme adımını her gece kendi staging ortamında uçtan uca test ediyor. Formun sonunda reCAPTCHA v2 var ve doğrulama ızgaraya düştüğü anda koşu kırmızıya dönüyor, sabah ilk iş biri gelip elle tıklıyor. Yukarıdaki dört adım koşuya eklendiğinde test insan müdahalesi olmadan tamamlanır.
Planlamaya iki maddeyi yazın:
- Eşzamanlılık. CaptchaAI planları thread bazlıdır; çözüm başına ücretlendirme yoktur ve plan içinde çözüm sayısı sınırsızdır. Tek bir gece koşusu için BASIC ($15/ay, 5 thread) yeterlidir. Paralel senaryo sayısı arttıkça STANDARD ($30/ay, 15 thread) veya ADVANCE ($90/ay, 50 thread) tarafına geçersiniz. Fiyatlar USD'dir; aylık maliyetin sabit kalması, kur dalgalanmasıyla yaşayan ekipler için tek başına bir planlama avantajıdır.
- KVKK. Test verisi üretirken üretim veritabanından gerçek müşteri kayıtlarını kopyalamayın.
+90biçiminde kurgusal telefon numaraları,tr-TRyerel ayarı veEurope/Istanbulsaat dilimiyle üretilmiş sahte bir veri seti hem gerçekçi olur hem de kişisel veri sorumluluğu doğurmaz.
Sık karşılaşılan sorunlar
| Sorun | Olası neden | Çözüm |
|---|---|---|
Yanıtta ERROR_ZERO_BALANCE |
Bakiye yok veya plan pasif | Panelden planı yenileyin |
| Dizi boş dönüyor | Talimat metni gönderilmedi | instructions alanını doldurun |
| Yanlış kutucuklar tıklanıyor | grid_size görselle uyumsuz |
4×4 ızgarada değeri 4x4 yapın |
tiles[...] tanımsız |
Ekran görüntüsü ana sayfadan alınmış | Görüntüyü bframe frame'inden alın |
| Doğrulama sonrası yeni ızgara geliyor | Çok turlu doğrulama | Yakalama ve gönderme adımlarını her turda tekrarlayın |
SSS
Ücretlendirme kutucuk başına mı yapılıyor?
Hayır. Faturalama eşzamanlı thread sayısına göredir ve plan içinde çözüm sayısı sınırsızdır. Bir görev tamamlandığı anda o thread bir sonrakini almaya hazır olur.
Çözüm ne kadar sürer?
Grid Image için yayımlanan hız tavanı 1 saniyenin altındadır. Örnekteki 5 saniyelik ilk beklemeyi kısaltarak toplam süreyi belirgin biçimde düşürebilirsiniz; çoğu koşuda sorgulama aralığı çözümün kendisinden uzun sürer.
4×4 ızgaralarda da çalışır mı?
Evet — grid_size alanını 4x4 olarak gönderin. Kutucuk numaralandırması aynı mantıkla 1'den 16'ya kadar gider.
CaptchaAI hCaptcha ızgaralarını çözüyor mu?
Hayır, hCaptcha desteklenmiyor. Bu akış reCAPTCHA v2 ızgaraları ile genel görüntü/OCR doğrulamaları içindir; GeeTest v4 için de yalnızca "çok yakında" ifadesi geçerlidir.
Aynı kodu sunucuda konteyner içinde çalıştırabilir miyim?
Evet. Puppeteer'ı headless modda başlatın ve konteyner imajına Chromium bağımlılıklarını ekleyin; API çağrılarında hiçbir değişiklik gerekmez. Playwright kullanıyorsanız yalnızca tarayıcı otomasyon katmanı değişir, in.php ve res.php istekleri aynı kalır.