Tutorials

CAPTCHA Çözme İşlemi: Saatte 10.000 Görev Nasıl İşlenir?

Saatte 10.000 CAPTCHA çözmenin sırrı daha hızlı bir servis değil, doğru eşzamanlılıktır. Tek bir çözüm ortalama 15 saniye sürerken bu hedefe ulaşmak için her an yaklaşık 42 çözüm isteğini aynı anda açık tutmanız yeterli.

Bu rehber üç şeyi somut olarak gösterir: eşzamanlılığı kuran mimari, çalışan Python ve Node.js kodu ve üretimde işe yarayan ince ayar değerleri. Tüm akış CaptchaAI API'si üzerine kuruludur ve gönder–sorgula (submit/poll) modelini temel alır.

Önce matematik: kaç eşzamanlı çözüm gerekir?

Tek bir reCAPTCHA v2 çözümü medyan 15 saniye sürüyorsa:

  • Sıralı (tek tek): 3.600 sn / 15 sn = saatte 240 çözüm
  • Saatte 10.000'e ulaşmak için: her an ~42 eşzamanlı çözüm açık olmalı

Önemli olan nokta şu: CaptchaAI'nin daha hızlı çözmesini beklemiyorsunuz. Aynı 15 saniyelik pencere içinde 42 çözümün tamamlanmasına yetecek kadar isteği üst üste bindiriyorsunuz. Yani darboğaz servisin hızı değil, sizin açık tutabildiğiniz eşzamanlı istek sayısıdır. 240 ile 10.000 arasındaki farkın tamamı bu paralellikten gelir.

Somut bir senaryo

Bir e-ticaret müşterisi için gece boyunca binlerce ödeme akışı QA senaryosu doğrulayan bir otomasyon geliştiricisi düşünün; her senaryoda reCAPTCHA v2 adımını çözmesi gerekiyor. Saatlik verim burada doğrudan teslim süresine dönüşür: hattı iki kat hızlandırmak, gece işini yarıya indirir. TL'nin oynaklığı nedeniyle thread bazlı, aylık USD sabit fiyatlı bir plan da bütçeyi önden öngörülebilir kılar.

Mimari: kuyruk, gönderim ve sorgulama katmanları

┌──────────┐     ┌────────────┐     ┌─────────────┐     ┌──────────┐
│  Task     │────▶│  Submit    │────▶│  CaptchaAI  │────▶│  Result  │
│  Queue    │     │  Workers   │     │  API        │     │  Store   │
│  (Redis)  │     │  (async)   │     │             │     │  (DB)    │
└──────────┘     └────────────┘     └─────────────┘     └──────────┘
                       │                    ▲
                       │    ┌──────────┐    │
                       └───▶│  Poll    │────┘
                            │  Workers │
                            └──────────┘

Boru hattı dört bileşenden oluşur:

  1. Görev kuyruğu — Bekleyen CAPTCHA görevlerini sitekey ve URL'leriyle birlikte tutar (Redis, RabbitMQ)
  2. Gönderim worker'ları — Görevleri CaptchaAI API'sine eşzamanlı olarak gönderir
  3. Sorgulama worker'ları — Sonuçları optimize edilmiş aralıklarla sorgular
  4. Sonuç deposu — Gelen token'ları geldikçe kaydeder

Gönder–sorgula döngüsü

Her görev iki aşamadan geçer. Önce in.php uç noktasına sitekey ve pageurl gönderilir; API bir görev kimliği (task ID) döndürür. Ardından bu kimlik, sonuç hazır olana kadar res.php üzerinden belirli aralıklarla sorgulanır. Verimi belirleyen üç ayar şunlardır:

  • INITIAL_WAIT — İlk sorgulamadan önce beklenen süre; çok erken sorgulama boşa giden istek demektir
  • POLL_INTERVAL — Sorgulamalar arasındaki aralık
  • MAX_CONCURRENT — Aynı anda açık tutulan çözüm sayısı

Python: Asenkron çözüm hattı

# high_throughput_solver.py
import os
import asyncio
import time
import aiohttp

API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
BASE_URL = "https://ocr.captchaai.com"
MAX_CONCURRENT = 50  # Max simultaneous solves
POLL_INTERVAL = 5    # Seconds between polls
INITIAL_WAIT = 12    # Seconds before first poll

semaphore = asyncio.Semaphore(MAX_CONCURRENT)
stats = {"submitted": 0, "solved": 0, "failed": 0, "start": 0}

async def solve_one(session, sitekey, pageurl, task_num):
    """Submit and poll a single CAPTCHA."""
    async with semaphore:
        try:
            # Submit
            async with session.get(f"{BASE_URL}/in.php", params={
                "key": API_KEY, "method": "userrecaptcha",
                "googlekey": sitekey, "pageurl": pageurl, "json": "1",
            }) as resp:
                result = await resp.json(content_type=None)

            if result.get("status") != 1:
                stats["failed"] += 1
                return None

            stats["submitted"] += 1
            task_id = result["request"]

            # Wait before first poll
            await asyncio.sleep(INITIAL_WAIT)

            # Poll
            for _ in range(25):
                async with session.get(f"{BASE_URL}/res.php", params={
                    "key": API_KEY, "action": "get",
                    "id": task_id, "json": "1",
                }) as resp:
                    poll_result = await resp.json(content_type=None)

                if poll_result.get("status") == 1:
                    stats["solved"] += 1
                    return poll_result["request"]

                if poll_result.get("request") != "CAPCHA_NOT_READY":
                    stats["failed"] += 1
                    return None

                await asyncio.sleep(POLL_INTERVAL)

            stats["failed"] += 1
            return None

        except Exception as e:
            stats["failed"] += 1
            return None

async def run_batch(tasks):
    """Process a batch of CAPTCHA tasks concurrently."""
    connector = aiohttp.TCPConnector(
        limit=MAX_CONCURRENT,
        keepalive_timeout=60,
    )
    async with aiohttp.ClientSession(connector=connector) as session:
        coros = [
            solve_one(session, task["sitekey"], task["pageurl"], i)
            for i, task in enumerate(tasks)
        ]
        results = await asyncio.gather(*coros)
    return results

async def main():
    # Generate test tasks (replace with your task source)
    tasks = [
        {
            "sitekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
            "pageurl": "https://www.google.com/recaptcha/api2/demo",
        }
        for _ in range(100)  # Start with 100 tasks
    ]

    stats["start"] = time.time()
    print(f"Processing {len(tasks)} tasks with {MAX_CONCURRENT} concurrent workers")

    results = await run_batch(tasks)
    elapsed = time.time() - stats["start"]

    print(f"\nCompleted in {elapsed:.0f}s")
    print(f"Submitted: {stats['submitted']}")
    print(f"Solved: {stats['solved']}")
    print(f"Failed: {stats['failed']}")
    print(f"Throughput: {stats['solved'] / (elapsed / 3600):.0f} solves/hour")

asyncio.run(main())

Node.js: Eşzamanlı çözüm hattı

// high_throughput_solver.js
const axios = require('axios');
const https = require('https');

const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
const BASE = 'https://ocr.captchaai.com';
const MAX_CONCURRENT = 50;

const agent = new https.Agent({ keepAlive: true, maxSockets: MAX_CONCURRENT });
const api = axios.create({ baseURL: BASE, httpsAgent: agent, timeout: 30000 });

const stats = { submitted: 0, solved: 0, failed: 0 };

async function solveOne(sitekey, pageurl) {
  try {
    const submit = await api.get('/in.php', {
      params: { key: API_KEY, method: 'userrecaptcha', googlekey: sitekey, pageurl, json: '1' },
    });
    if (submit.data.status !== 1) { stats.failed++; return null; }
    stats.submitted++;

    await new Promise(r => setTimeout(r, 12000));

    for (let i = 0; i < 25; i++) {
      const poll = await api.get('/res.php', {
        params: { key: API_KEY, action: 'get', id: submit.data.request, json: '1' },
      });
      if (poll.data.status === 1) { stats.solved++; return poll.data.request; }
      if (poll.data.request !== 'CAPCHA_NOT_READY') { stats.failed++; return null; }
      await new Promise(r => setTimeout(r, 5000));
    }
    stats.failed++;
    return null;
  } catch { stats.failed++; return null; }
}

async function runWithConcurrency(tasks, limit) {
  const results = [];
  const executing = new Set();

  for (const task of tasks) {
    const p = solveOne(task.sitekey, task.pageurl).then(r => {
      executing.delete(p);
      return r;
    });
    executing.add(p);
    results.push(p);

    if (executing.size >= limit) {
      await Promise.race(executing);
    }
  }
  return Promise.all(results);
}

(async () => {
  const tasks = Array.from({ length: 100 }, () => ({
    sitekey: '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
    pageurl: 'https://www.google.com/recaptcha/api2/demo',
  }));

  const start = Date.now();
  console.log(`Processing ${tasks.length} tasks, ${MAX_CONCURRENT} concurrent`);

  await runWithConcurrency(tasks, MAX_CONCURRENT);
  const elapsed = (Date.now() - start) / 1000;

  console.log(`\nDone in ${elapsed.toFixed(0)}s`);
  console.log(`Solved: ${stats.solved}, Failed: ${stats.failed}`);
  console.log(`Throughput: ${(stats.solved / (elapsed / 3600)).toFixed(0)} solves/hour`);

  agent.destroy();
})();

Verimi izleyin: gerçek zamanlı metrikler

Ölçmeden ayar yapamazsınız. Hattı çalıştırırken şu dört metriği canlı takip edin:

  • Dakika başına çözüm — 10.000/saat hedefi için ~167 civarında kalmalı
  • Hata oranı — %5'in altında tutun; sıçrarsa eşzamanlılığı düşürün
  • Kuyruk derinliği — Büyüyorsa worker ekleyin; sürekli boşsa fazla provizyon yapmışsınız demektir
  • P90 çözüm süresi — Artıyorsa CaptchaAI istek sınırlaması uyguluyor olabilir

İnce ayar parametreleri

Bu metrikler ışığında dört değişkeni ayarlarsınız. Aşağıdaki tablo üç başlangıç profili verir:

Parametre Muhafazakâr Dengeli Agresif
MAX_CONCURRENT 20 50 100
INITIAL_WAIT 15 sn 12 sn 10 sn
POLL_INTERVAL 7 sn 5 sn 3 sn
MAX_POLL_ATTEMPTS 30 25 20
Beklenen verim ~4.800/saat ~10.000/saat ~18.000/saat

Hangi profille başlamalı?

  • Muhafazakâr — Yeni entegrasyon veya küçük plan; hata oranını gözlemleyin
  • Dengeli — 10.000/saat hedefi için varsayılan başlangıç noktası
  • Agresif — Yalnızca büyük thread tahsisi ve stabil hata oranıyla

İhtiyatlı başlayın; azalan getiriler ya da artan hata oranı görene kadar MAX_CONCURRENT değerini kademeli artırın.

Eşzamanlılık planınıza bağlıdır

CaptchaAI faturalandırması eşzamanlı thread üzerinden yapılır: bir thread = aynı anda işlemdeki bir CAPTCHA. MAX_CONCURRENT değeriniz planınızın thread sayısını aşamaz. 50 eşzamanlı çözüm için ADVANCE ($90/ay, 50 thread), 100 için PREMIUM ($170/ay, 100 thread) gerekir. Her planda thread başına çözüm sınırsızdır; günlük kota ya da çözüm başı ücret yoktur — verimi yalnızca thread tahsisiniz ve tür bazlı çözüm hızı sınırlar.

Sorun giderme

Sorun Sebep Çözüm
Verim ~5.000/saatte takılıyor Yetersiz eşzamanlılık MAX_CONCURRENT'i 80–100'e çıkarın
Hata oranı %10'un üzerinde API'yi aşırı yükleme veya sağlıksız proxy'ler Eşzamanlılığı düşürün, proxy sağlığını kontrol edin
Bellek kullanımı sürekli artıyor Sınırsız görev birikimi Sonuçları geldikçe işleyin, tamponda biriktirmeyin
ERROR_NO_SLOT_AVAILABLE CaptchaAI kuyruğu dolu Geri çekilip 5 saniye sonra yeniden deneyin

KVKK ve yetkili kullanım

Yüksek hacimli otomasyon kurarken yalnızca yetkiniz olan iş akışlarını hedefleyin. İşlediğiniz veriler kişisel veri içeriyorsa bunlar KVKK kapsamına girer; bu nedenle CaptchaAI'yi izinli QA ve veri toplama süreçleri içinde kullanın. Test verilerinde staging.example.com gibi kendi ortamlarınızı tercih edin, canlı üçüncü taraf hedeflerini değil.

Sık sorulan sorular

Saatte 10.000 çözüm için hangi CaptchaAI planı gerekir?

Verim, eşzamanlı thread sayınıza bağlıdır. 50 eşzamanlı çözüm ADVANCE ($90/ay, 50 thread), 100 eşzamanlı çözüm PREMIUM ($170/ay, 100 thread) ile karşılanır. Thread başına çözüm sınırsız olduğundan aylık maliyet öngörülebilir kalır.

MAX_CONCURRENT değerini çok yükseltirsem ne olur?

Eşzamanlı istek sayısında kesin bir üst sınır yok; ancak aşırı yüksek değerler (500+) istek sınırlamasını tetikleyebilir. 50'den başlayıp hata oranı artana kadar kademeli çıkın.

Aynı boru hattı reCAPTCHA dışındaki türlerde de çalışır mı?

Evet. Mimari türden bağımsızdır; yalnızca method ve gönderdiğiniz parametreler değişir. Turnstile, GeeTest v3, image/OCR gibi desteklenen türler aynı gönder–sorgula döngüsünü kullanır. (hCaptcha ve FunCaptcha desteklenmez.)

Bir çözüm 15 saniyeden uzun sürerse ne olur?

Sorgulama döngüsü sonucu MAX_POLL_ATTEMPTS kez, POLL_INTERVAL aralığıyla sorgular. Bu pencerede token gelmezse görev başarısız sayılıp sıradaki teste geçilir; askıda kalan tek istek verimi düşürmez.

Sonraki adımlar

Yüksek hacimli çözüm hattınızı kurmaya bugün başlayın — CaptchaAI API anahtarınızı alın.

İlgili rehberler:

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