Tutoriales

Conexión Keep-Alive y HTTP/2 para llamadas API CAPTCHA más rápidas

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

Los comentarios están deshabilitados para este artículo.