Cada resolución de CAPTCHA implica múltiples solicitudes HTTP: un envío y entre 3 y 10 sondeos. Sin reutilización de la conexión, cada solicitud paga el costo de un nuevo TCP handshake y negociación TLS: 100 a 300 ms por conexión. Esta guía muestra cómo eliminar esa sobrecarga usando conexiones keep-alive y multiplexación HTTP/2 con CaptchaAI.
Por qué es importante la reutilización de conexiones
Una solución típica de reCAPTCHA v2 requiere:
- 1 enviar solicitud a
in.php - 4 a 6 solicitudes de consulta para
res.php - Total: 5 a 7 solicitudes HTTP
Sin keep-alive:
- 5 × (TCP handshake ~50 ms + TLS ~100 ms) = 750 ms de sobrecarga
Con keep-alive:
- 1 × (TCP + TLS) + 4 × (~5 ms de reutilización) = 170 ms de sobrecarga
Ahorro: ~580 ms por solución. Con 10 000 soluciones/day, eso equivale a 1,6 horas de latencia ahorrada.
Python: uso de requests.Session
La biblioteca requests admite keep-alive de forma predeterminada cuando se usa un objeto Session:
# 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: HTTP/2 con httpx
Para compatibilidad con HTTP/2, usa httpx:
# 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()
JavaScript: uso de una instancia de Axios con keep-alive
// 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();
})();
HTTP/2 vs HTTP/1.1 para resolver CAPTCHA
| Característica | HTTP/1.1 Keep-Alive | HTTP/2 |
|---|---|---|
| Reutilización de la conexión | Sí (secuencial) | Sí (multiplexado) |
| Flujos simultáneos | 1 por conexión | Hasta 100+ por conexión |
| Compresión de cabeceras | No | HPACK |
| Reducción de latencia | ~60% | ~70% |
| Requiere soporte del navegador | No | No (llamadas API) |
| Ideal para | Resoluciones secuenciales | Resoluciones paralelas |
Para la resolución secuencial (un CAPTCHA a la vez), HTTP/1.1 keep-alive es suficiente. Para la resolución en paralelo (múltiples CAPTCHA simultáneamente), la multiplexación HTTP/2 proporciona un beneficio adicional al compartir una única conexión.
Dimensionamiento del grupo de conexiones
Haga coincidir el tamaño de su grupo con su nivel de concurrencia:
| Resoluciones concurrentes | Tamaño de pool recomendado |
|---|---|
| 1–5 | 5 conexiones |
| 5–20 | 10 conexiones |
| 20–50 | 25 conexiones |
| 50–100 | 50 conexiones |
| 100+ | Usa HTTP/2 (1 conexión) |
Los pools de gran tamaño desperdician memoria. Los pools de tamaño insuficiente obligan a nuevas conexiones, anulando los beneficios del keep-alive.
Solución de problemas
| Problema | Causa | Solución |
|---|---|---|
| Se cierran conexiones entre sondeos | Timeout del servidor o proxy | Establece el timeout de keep-alive por encima de 30 s en la configuración del cliente |
| Sin mejora de rendimiento | Ya se usa keep-alive (predeterminado en algunas librerías) | Verifica con herramientas de monitoreo de red |
| Errores de conexión rechazada | Pool agotado | Aumenta maxSockets o reduce la concurrencia |
| HTTP/2 no negociado | El servidor no soporta h2 | Recurre a HTTP/1.1 keep-alive |
Preguntas frecuentes
¿CaptchaAI es compatible con HTTP/2?
Prueba con curl --http2 https://ocr.captchaai.com/res.php para verificar. Si el servidor negocia h2, tu cliente HTTP/2 se beneficiará. De lo contrario, recurre a HTTP/1.1 keep-alive.
¿Debo cerrar sesiones después de cada lote?
No. Mantén la sesión abierta entre lotes si ejecutas soluciones periódicas. Ciérrala solo cuando tu aplicación se cierre.
¿Esto funciona con proxies?
Sí, pero el proxy también debe admitir keep-alive y HTTP/2. Algunos proxies SOCKS5 no mantienen conexiones persistentes.
Artículos relacionados
- Circuit breaker para llamadas API CAPTCHA
- Dimensionamiento del pool de conexiones para clientes API CAPTCHA
- Benchmarking de tiempos de resolución de CAPTCHA