CAPTCHA API çağrılarınız beklediğinizden yavaşsa, darboğaz çoğu zaman çözüm süresinde değildir — asıl kayıp, her istekte yeniden kurulan TCP ve TLS el sıkışmasındadır. Tek bir CAPTCHA çözümü bir gönderme ve ardından 3–10 sorgulama isteği demektir; bağlantıyı yeniden kullanmazsanız her istek 100–300 ms'lik kurulum maliyetini yeniden öder. Çözüm ikilidir: bağlantıyı canlı tutmak (keep-alive) ve HTTP/2 çoğullama. Bu rehberde CaptchaAI ile bu ek yükü Python ve Node.js'te çalışan kodla nasıl sıfıra yakın indireceğinizi göreceksiniz.
Bağlantı yeniden kullanımı çözüm başına ne kadar kazandırır?
Tipik bir reCAPTCHA v2 çözümü şunları içerir:
in.php'ye 1 gönderme isteğires.php'ye 4–6 sorgulama isteği- Toplam: 5–7 HTTP isteği
Bağlantıyı canlı tutmadan:
- 5 × (TCP el sıkışması ~50 ms + TLS ~100 ms) = 750 ms ek yük
Bağlantıyı canlı tutarak:
- 1 × (TCP + TLS) + 4 × (~5 ms yeniden kullanım) = 170 ms ek yük
Kazanç: çözüm başına ~580 ms. Günde 10.000 çözümde bu, 1,6 saatlik birikmiş gecikme demektir. Fark tek çözümde önemsiz görünebilir; ancak thread tabanlı bir planla paralel çalışıyorsanız (örneğin ADVANCE, $90/ay, 50 thread) biriken gecikme doğrudan işlem hacminizi düşürür.
Kod yazmadan önce iki kararı verin: protokol ve havuz boyutu
Uygulamaya geçmeden iki şeyi netleştirin — bunlar sonraki bölümlerdeki tüm örneklerin temelini belirler: hangi protokolü kullanacağınız ve havuzu ne kadar büyük tutacağınız.
HTTP/1.1 keep-alive mi, HTTP/2 mi?
Önce protokolü seçin. Doğru seçim, sıralı mı yoksa paralel mi çözüm yaptığınıza bağlıdır:
| Özellik | HTTP/1.1 Keep-Alive | HTTP/2 |
|---|---|---|
| Bağlantı yeniden kullanımı | Evet (sıralı) | Evet (çoğullanmış) |
| Eşzamanlı akışlar | Bağlantı başına 1 | Bağlantı başına 100'den fazla |
| Başlık sıkıştırması | Yok | HPACK sıkıştırması |
| Gecikme azaltma | ~%60 | ~%70 |
| Tarayıcı desteği gerekir mi? | Hayır | Hayır (API çağrıları) |
| En uygun kullanım | Sıralı çözümler | Paralel çözümler |
Sıralı çözümde (aynı anda tek CAPTCHA) HTTP/1.1 canlı tutma yeterlidir. Paralel çözümde HTTP/2 çoğullaması tek bağlantıyı paylaşarak ek kazanç sağlar; 100'ün üzerinde eşzamanlı çözümde ise HTTP/2 pratikte tek makul seçenektir.
İpucu: Emin değilseniz HTTP/1.1 canlı tutmayla başlayın. Ölçeğiniz büyüdüğünde HTTP/2'ye geçmek çoğu istemcide tek satırlık bir yapılandırma değişikliğidir.
Bağlantı havuzunu eşzamanlılığa göre boyutlandırın
İkinci karar havuz boyutu. Havuzunuzu eşzamanlılık seviyenizle eşleştirin:
| Eşzamanlı çözümler | Önerilen havuz boyutu |
|---|---|
| 1–5 | 5 bağlantı |
| 5–20 | 10 bağlantı |
| 20–50 | 25 bağlantı |
| 50–100 | 50 bağlantı |
| 100+ | HTTP/2 kullanın (1 bağlantı) |
Büyük havuzlar belleği boşa harcar. Küçük havuzlar sürekli yeni bağlantı kurmaya zorlayarak canlı tutmanın avantajını yok eder. Pratik kural: havuz boyutunu planınızın thread sayısıyla hizalayın.
Örnek: gece çalışan bir QA doğrulama işi
İstanbul merkezli bir otomasyon geliştiricisinin, bir e-ticaret projesinin staging ortamında her gece yüzlerce ödeme akışını doğruladığını düşünün. Her sayfa reCAPTCHA v2 içeriyorsa ve iş Europe/Istanbul saatiyle 03:00'te koşuyorsa, bağlantı başına 580 ms'lik ek yük binlerce çözümde saatlere ulaşır. ADVANCE planındaki 50 thread'i tam kullanmak için havuz boyutunu 50'ye yakın tutmak, işin sabah raporundan önce bitmesini sağlar.
Python: requests.Session ile kalıcı bağlantı
Kararlarınızı verdiğinize göre uygulamaya geçebiliriz. requests kitaplığı bir Session nesnesi kullandığınızda canlı tutmayı varsayılan olarak destekler. Tek yapmanız gereken her çözüm için yeni bir istemci kurmak yerine aynı oturumu paylaşmaktır:
# keepalive_solver.py
import os
import time
import requests
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
# Create a session — reuses TCP connections across requests
session = requests.Session()
session.headers.update({"Connection": "keep-alive"})
def solve_captcha(sitekey, pageurl):
"""Solve reCAPTCHA v2 using a persistent connection."""
# Submit — uses existing connection if available
resp = session.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
})
result = resp.json()
if result.get("status") != 1:
raise Exception(f"Submit failed: {result.get('request')}")
task_id = result["request"]
# Poll — reuses the same connection
time.sleep(15)
for _ in range(25):
poll = session.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": "1",
})
poll_result = poll.json()
if poll_result.get("status") == 1:
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {poll_result.get('request')}")
time.sleep(5)
raise Exception("Timeout")
# Solve multiple CAPTCHAs reusing the same connection
for i in range(5):
token = solve_captcha(
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"https://www.google.com/recaptcha/api2/demo"
)
print(f"Solve {i+1}: {token[:30]}...")
Python: httpx ile HTTP/2 çoğullama
Sıralı çözümlerde Session fazlasıyla yeterlidir. Ancak çok sayıda çözümü aynı anda paralel yürütüyorsanız HTTP/2 çoğullaması tek bir bağlantı üzerinden birden çok akışı taşır. httpx bunu tek satırlık bir yapılandırmayla açar:
# http2_solver.py
import os
import time
import httpx
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
BASE_URL = "https://ocr.captchaai.com"
# HTTP/2 client with connection pooling
client = httpx.Client(http2=True, timeout=30.0)
def solve_captcha(sitekey, pageurl):
"""Solve using HTTP/2 multiplexed connections."""
resp = client.get(f"{BASE_URL}/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": "1",
})
result = resp.json()
if result.get("status") != 1:
raise Exception(f"Submit failed: {result.get('request')}")
task_id = result["request"]
time.sleep(15)
for _ in range(25):
poll = client.get(f"{BASE_URL}/res.php", params={
"key": API_KEY, "action": "get",
"id": task_id, "json": "1",
})
poll_result = poll.json()
if poll_result.get("status") == 1:
return poll_result["request"]
if poll_result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {poll_result.get('request')}")
time.sleep(5)
raise Exception("Timeout")
# Multiple solves over a single HTTP/2 connection
for i in range(5):
token = solve_captcha(
"6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"https://www.google.com/recaptcha/api2/demo"
)
print(f"Solve {i+1}: {token[:30]}...")
client.close()
Node.js: Axios ve keep-alive agent yapılandırması
Node.js tarafında http ve https modüllerinin Agent sınıfını keepAlive: true ile oluşturur ve Axios örneğine bağlarsınız. maxSockets değeri havuzdaki eşzamanlı bağlantı sayısını sınırlar:
// keepalive_solver.js
const axios = require('axios');
const http = require('http');
const https = require('https');
const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
// Create agents with keep-alive enabled
const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 10 });
const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 10 });
// Axios instance with persistent connections
const api = axios.create({
baseURL: 'https://ocr.captchaai.com',
httpAgent,
httpsAgent,
timeout: 30000,
});
async function solveCaptcha(sitekey, pageurl) {
// Submit — reuses connection
const submit = await api.get('/in.php', {
params: {
key: API_KEY, method: 'userrecaptcha',
googlekey: sitekey, pageurl, json: '1',
},
});
if (submit.data.status !== 1) throw new Error(submit.data.request);
const taskId = submit.data.request;
// Poll — reuses same connection
await new Promise(r => setTimeout(r, 15000));
for (let i = 0; i < 25; i++) {
const poll = await api.get('/res.php', {
params: { key: API_KEY, action: 'get', id: taskId, json: '1' },
});
if (poll.data.status === 1) return poll.data.request;
if (poll.data.request !== 'CAPCHA_NOT_READY') throw new Error(poll.data.request);
await new Promise(r => setTimeout(r, 5000));
}
throw new Error('Timeout');
}
(async () => {
for (let i = 0; i < 5; i++) {
const token = await solveCaptcha(
'6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'https://www.google.com/recaptcha/api2/demo'
);
console.log(`Solve ${i + 1}: ${token.slice(0, 30)}...`);
}
// Clean up agents
httpAgent.destroy();
httpsAgent.destroy();
})();
Keep-alive'in gerçekten çalıştığını nasıl doğrularsınız?
Kod çalışıyor görünse bile bağlantının gerçekten yeniden kullanıldığını varsaymayın; birkaç dakikalık kontrol, "hiçbir şey değişmedi" şikayetinin nedenini net ortaya koyar:
curl --http2 https://ocr.captchaai.com/res.phpile sunucunun HTTP/2 anlaşmasını (h2) kabul edip etmediğini görün. Kabul etmiyorsa HTTP/2 istemcisi otomatik olarak HTTP/1.1 canlı tutmaya düşer; sorun değil, kod yine de çalışır.- İşletim sisteminizde
ss -tanveyanetstatileocr.captchaai.com'a açık bağlantı sayısını izleyin: sayı sabit kalıyorsa havuz yeniden kullanılıyor demektir; her çözümde artıyorsa bağlantılar boşuna yeniden kuruluyordur. - İlk çözümün süresini sonrakilerle karşılaştırın. Canlı tutma çalışıyorsa el sıkışma maliyeti yalnızca ilk istekte ödenir ve sonraki çözümlerin gecikmesi belirgin biçimde düşer.
Üç kontrol de aynı yöne işaret ediyorsa yapılandırmanız doğru; işaret etmiyorsa aşağıdaki sorun giderme tablosuna bakın.
Not: "Performans değişmedi" şikayetlerinin çoğu, istemci kitaplığının zaten canlı tutmayı varsayılan açtığı ve asıl gecikmenin başka bir katmanda (proxy, DNS veya çözüm kuyruğu) olduğu durumlardan kaynaklanır.
Sık karşılaşılan sorunlar ve çözümleri
| Sorun | Neden | Çözüm |
|---|---|---|
| Sorgulamalar arasında bağlantılar kapanıyor | Sunucu veya proxy zaman aşımı | İstemci yapılandırmasında keep-alive zaman aşımını 30 saniyenin üzerine ayarlayın |
| Performans değişmiyor | Kitaplık zaten canlı tutuyor (bazılarında varsayılan) | Ağ izleme araçlarıyla doğrulayın |
| "Connection refused" hataları | Havuz tükendi | maxSockets değerini artırın veya eşzamanlılığı azaltın |
| HTTP/2 anlaşması sağlanamadı | Sunucu h2 desteklemiyor | HTTP/1.1 canlı tutmaya geri dönün |
Sık sorulan sorular
Bağlantıyı canlı tutmak çözüm başarı oranını etkiler mi?
Hayır. Canlı tutma yalnızca ağ katmanındaki gecikmeyi düşürür; CAPTCHA'nın çözülüp çözülmediğini etkilemez. Başarı oranı çözüm motoruna bağlıdır, taşıma bağlantısına değil.
HTTP/1.1 yerine HTTP/2'yi ne zaman tercih etmeliyim?
Aynı anda 100'den fazla eşzamanlı çözüm çalıştırdığınızda. Bu eşiğin altında HTTP/1.1 canlı tutma ve makul boyutlu bir bağlantı havuzu genellikle aynı performansı verir.
requests.Session zaten canlı tutuyorsa ek yapılandırmaya gerek var mı?
Çoğu durumda hayır. Session nesnesi TCP bağlantılarını otomatik yeniden kullanır. Yalnızca varsayılan havuz sınırını (pool_maxsize) yüksek eşzamanlılığa göre yükseltmeniz gerekebilir.
Bağlantı havuzu boyutu ile plan thread sayım aynı mı olmalı?
Aynı olması şart değil, ama uyumlu olmalı. Havuzunuz thread sayınızdan küçükse thread'leri tam kullanamaz; çok büyükse boşta bağlantılarla bellek harcarsınız. 50 thread'lik bir planda 25–50 bağlantı iyi bir dengedir.
Özetle: hangi ayarı ne zaman kullanmalı?
Tek cümleyle: bağlantıyı yeniden kullanın, ölçeğe göre protokolü seçin.
- Sıralı, düşük hacimli çözümler:
requests.Session(Python) veya keep-alive agent'lı Axios (Node.js) yeterlidir. - Yüksek eşzamanlılık (yüzlerce paralel çözüm):
httpxile HTTP/2 çoğullamaya geçin. - Her durumda: havuz boyutunu planınızın thread sayısıyla hizalayın ve
ss/netstatile açık bağlantı sayısını doğrulayın.
İlgili makaleler
- devre kesici (circuit breaker) modeliyle CAPTCHA API çağrıları
- CAPTCHA API istemcileri için bağlantı havuzu boyutlandırma
Sonraki adım
Her çözümdeki bağlantı yükünü düşürün — CaptchaAI API anahtarınızı alın.
İlgili kılavuzlar: