Solución de Problemas

Límites de concurrencia en CaptchaAI: diagnóstico y correcciones

Cuando ejecuta demasiadas tareas CAPTCHA paralelas, CaptchaAI devuelve ERROR_NO_SLOT_AVAILABLE. Esto significa que ha excedido el límite de tareas simultáneas de su cuenta. Esta guía explica los límites, cómo manejarlos y cómo maximizar el rendimiento sin alcanzar el límite.


Síntomas

lo que ves causa
ERROR_NO_SLOT_AVAILABLE Demasiadas tareas activas a la vez
Respuestas HTTP 429 Demasiadas solicitudes por segundo al endpoint API
Algunas tareas tienen éxito, otras fallan Se alcanza el límite de forma intermitente
Los tiempos de resolución aumentan Congestión de cola en tu cuenta

Entendiendo los límites

CaptchaAI tiene dos tipos de límites de tarifas:

Tipo de límite lo que controla error
Tareas simultáneas Número máximo de tareas resueltas simultáneamente ERROR_NO_SLOT_AVAILABLE
Tarifa de solicitud Máximo de llamadas API por segundo para enviar puntos finales /poll HTTP 429

Tu límite de tareas concurrentes depende de tu plan. Consulta tu panel de control en captchaai.com para ver tu límite actual.


Solución 1: agregue un semáforo para limitar la simultaneidad

Controle cuántas tareas se ejecutan en paralelo:

import requests
import time
import threading

API_KEY = "YOUR_API_KEY"
MAX_CONCURRENT = 20  # Stay below your account limit

semaphore = threading.Semaphore(MAX_CONCURRENT)


def solve_captcha(params):
    """Solve a CAPTCHA with concurrency control."""
    with semaphore:
        params["key"] = API_KEY
        params["json"] = 1

        submit = requests.post("https://ocr.captchaai.com/in.php", data=params).json()
        if submit.get("status") != 1:
            raise RuntimeError(f"Submit: {submit.get('request')}")

        task_id = submit["request"]
        time.sleep(10)

        for _ in range(30):
            result = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": API_KEY, "action": "get", "id": task_id, "json": 1
            }).json()
            if result.get("status") == 1:
                return result["request"]
            if result.get("request") != "CAPCHA_NOT_READY":
                raise RuntimeError(f"Solve: {result['request']}")
            time.sleep(5)
        raise TimeoutError("Timed out")

Solución 2: vuelva a intentarlo con ERROR_NO_SLOT_AVAILABLE

Cuando alcance el límite, espere y vuelva a intentarlo en lugar de fallar inmediatamente:

def submit_with_retry(params, max_retries=5):
    """Submit with automatic retry for slot errors."""
    params["key"] = API_KEY
    params["json"] = 1

    for attempt in range(max_retries):
        resp = requests.post("https://ocr.captchaai.com/in.php", data=params).json()

        if resp.get("status") == 1:
            return resp["request"]

        error = resp.get("request", "")
        if error == "ERROR_NO_SLOT_AVAILABLE":
            wait = 2 ** attempt  # Exponential backoff: 1, 2, 4, 8, 16 seconds
            print(f"No slot available, retrying in {wait}s (attempt {attempt + 1})")
            time.sleep(wait)
            continue
        else:
            raise RuntimeError(f"Submit error: {error}")

    raise RuntimeError("Max retries exceeded — no slots available")

Solución 3: use una cola de tareas

En lugar de inundar la API, ponga en cola las tareas y procéselas a un ritmo controlado:

from queue import Queue
from threading import Thread

task_queue = Queue()
results = {}


def worker():
    while True:
        task_id_local, params = task_queue.get()
        try:
            token = solve_captcha(params)
            results[task_id_local] = {"status": "ok", "token": token}
        except Exception as e:
            results[task_id_local] = {"status": "error", "message": str(e)}
        finally:
            task_queue.task_done()


# Start worker threads (limited by semaphore)
for _ in range(MAX_CONCURRENT):
    t = Thread(target=worker, daemon=True)
    t.start()

# Add tasks to queue
captcha_tasks = [
    {"method": "userrecaptcha", "googlekey": "KEY1", "pageurl": "https://site1.com"},
    {"method": "userrecaptcha", "googlekey": "KEY2", "pageurl": "https://site2.com"},
    # ... more tasks
]

for i, params in enumerate(captcha_tasks):
    task_queue.put((i, params))

task_queue.join()
print(f"Completed: {len(results)} tasks")

Solución 4: reducir la frecuencia de las consultas

Las consultas con demasiada frecuencia desperdician llamadas API y pueden activar límites de velocidad:

# WRONG — polling every 1 second
time.sleep(1)

# CORRECT — poll every 5 seconds
time.sleep(5)

# BETTER — wait longer on initial delay, then poll
time.sleep(15)  # Initial wait
for _ in range(20):
    # ... poll
    time.sleep(5)

Monitoreo de tareas activas

Realice un seguimiento de cuántas tareas están activas actualmente:

active_count = 0
lock = threading.Lock()

def track_solve(params):
    global active_count
    with lock:
        active_count += 1
        print(f"Active tasks: {active_count}/{MAX_CONCURRENT}")
    try:
        return solve_captcha(params)
    finally:
        with lock:
            active_count -= 1

Preguntas frecuentes

¿Cuál es el límite predeterminado de tareas simultáneas?

Depende de su plan de cuenta. Consulte su panel de control CaptchaAI para conocer su límite actual. Puede aumentarlo actualizando su plan.

¿Las consultas cuentan para el límite de tasa?

Sí. Cada solicitud res.php cuenta. Consulta cada 5 segundos, no cada 1 segundo.

¿Puedo aumentar mi límite concurrente?

Sí. Comuníquese con el soporte de CaptchaAI o actualice su plan para aumentar la cantidad máxima de tareas simultáneas.

¿Cuál es la diferencia entre ERROR_NO_SLOT_AVAILABLE y HTTP 429?

ERROR_NO_SLOT_AVAILABLE significa que se están resolviendo demasiadas tareas. HTTP 429 significa demasiadas solicitudes de API por segundo (incluso solo sondeos). Ambos requieren dar marcha atrás.


Escala tu resolución con CaptchaAI

Maximiza el rendimiento en captchaai.com.


Guías relacionadas

  • Limitación de tasa en tus propias solicitudes CAPTCHA

Configuración recomendada para su pipeline

Use exactamente la misma configuración de navegador en todos sus entornos de QA, staging y CI. Esto evita que un test funcione en local y falle en CI sin razón aparente.

from selenium import webdriver

def make_driver(headless: bool = True) -> webdriver.Chrome:
    options = webdriver.ChromeOptions()
    if headless:
        options.add_argument('--headless=new')
    options.add_argument('--window-size=1280,800')
    options.add_argument('--lang=es-ES')
    return webdriver.Chrome(options=options)

Mantener viewport, idioma y user-agent por defecto idénticos en todos los runners reduce la varianza y facilita comparar resultados entre ejecuciones de su propio QA.

Cómo se integra CaptchaAI en su pipeline propio

El patrón de integración con CaptchaAI siempre es el mismo, independientemente del lenguaje o framework de pruebas que use:

  1. Su test detecta el widget de CAPTCHA en la página de su propia aplicación (formulario de QA, landing de staging, endpoint de preproducción).
  2. Su test envía a CaptchaAI los datos públicos del widget (sitekey, URL de la página, tipo de CAPTCHA).
  3. CaptchaAI devuelve un token válido para esa página.
  4. Su test inyecta ese token en el campo correspondiente y envía el formulario.
  5. Su backend verifica el token con el proveedor de CAPTCHA, exactamente igual que con un usuario real.

Este flujo se aplica únicamente a integraciones que usted controla. No se utiliza para sortear protecciones de sitios de terceros.

Métricas y observabilidad

Incluya métricas específicas para los pasos relacionados con CAPTCHA en sus pipelines de QA. Esto le permite detectar regresiones en su propia integración antes de que lleguen a producción:

  • Tiempo de resolución por intento — desde la solicitud a CaptchaAI hasta la entrega del token.
  • Tasa de éxito por endpoint propio — cuántas verificaciones backend pasan respecto al total de intentos.
  • Distribución de errores — agrupados por código (ERROR_*, timeouts internos, fallos de red).
  • Latencia extremo a extremo — incluyendo render de la página, resolución de CAPTCHA y respuesta de su backend.

Conserve trazas (logs, capturas, HAR) durante un período razonable para poder reproducir incidentes en su entorno QA cuando un test falle de forma intermitente.

Buenas prácticas en su entorno QA

  • Pruebe siempre sobre su propia aplicación o sobre entornos explícitamente autorizados.
  • Mantenga una API key de CaptchaAI separada para QA, distinta de la de producción, para no mezclar métricas.
  • Defina timeouts y reintentos razonables (backoff exponencial) para no acumular trabajos pendientes en CaptchaAI durante caídas.
  • Versione sus snapshots de configuración (sitekey, action, umbrales) junto al código de los tests.
  • Revise periódicamente el changelog de su proveedor de CAPTCHA para anticipar cambios que afecten a su propia integración.

Solución de problemas

Síntoma Acción recomendada
El test no detecta el widget Revise selectores y tiempos en su entorno staging
CaptchaAI devuelve ERROR_NO_SLOT_AVAILABLE Reintente con backoff en su pipeline interna
La validación backend rechaza el token Compare action/sitekey con su configuración real
El test funciona en local pero falla en CI Iguale viewport, idioma y user-agent en ambos entornos
Tiempos de resolución muy variables Revise concurrencia y límites de su API key de CaptchaAI

Valide sus integraciones CAPTCHA en entornos propios con CaptchaAI.

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