CaptchaAI maneja alta concurrencia, pero es posible que desees limitarlo tú mismo. Motivos: control de costos, evitar picos involuntarios debido a errores, compartir recursos de manera justa entre equipos o igualar los límites de tasa establecidos por los sitios de destino. Esta guía implementa tres patrones de limitación de velocidad del lado del cliente paraCaptchaAI.
Por qué limitar la tarifa del lado del cliente
| Escenario | Sin limite | Con limite |
|---|---|---|
| El error causa un bucle de resolución infinito | Quema a través del equilibrio | Se detiene en el límite configurado |
| Varios equipos comparten una clave API | Gasto descoordinado | Asignación justa por equipo |
| Prohibiciones de sitios objetivo en > 100 req/min | Las cuentas se bloquean | Se mantiene por debajo del umbral |
| El presupuesto es de $50/month | Podría superar en una tarde | Se aplica un límite máximo |
Patrón 1: Cubo de fichas
Un depósito de tokens permite ráfagas al tiempo que aplica una tasa promedio. Los tokens se reponen a una tasa fija; cada solicitud consume un token.
Cubo de tokens de Python
# token_bucket_solver.py
import os
import time
import threading
import requests
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
class TokenBucket:
"""Token bucket rate limiter."""
def __init__(self, rate, capacity):
"""
rate: tokens added per second
capacity: max tokens (burst size)
"""
self.rate = rate
self.capacity = capacity
self.tokens = capacity
self.last_refill = time.monotonic()
self.lock = threading.Lock()
def acquire(self, timeout=30):
"""Wait for a token. Returns True if acquired, False on timeout."""
deadline = time.monotonic() + timeout
while True:
with self.lock:
self._refill()
if self.tokens >= 1:
self.tokens -= 1
return True
if time.monotonic() >= deadline:
return False
time.sleep(0.1)
def _refill(self):
now = time.monotonic()
elapsed = now - self.last_refill
self.tokens = min(self.capacity, self.tokens + elapsed * self.rate)
self.last_refill = now
# Allow 10 solves/minute with burst of 5
limiter = TokenBucket(rate=10/60, capacity=5)
def solve_rate_limited(sitekey, pageurl):
"""Solve with rate limiting."""
if not limiter.acquire(timeout=60):
raise Exception("Rate limit: could not acquire token within 60s")
session = requests.Session()
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"]
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")
Patrón 2: Mostrador de ventana corrediza
Realiza un seguimiento del número de solicitudes dentro de un período de tiempo fijo. Más simple que el depósito de fichas pero sin control de ráfagas.
Ventana deslizante de JavaScript
// sliding_window_solver.js
const axios = require('axios');
const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
class SlidingWindowLimiter {
constructor(maxRequests, windowMs) {
this.maxRequests = maxRequests;
this.windowMs = windowMs;
this.timestamps = [];
}
async acquire(timeoutMs = 60000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
// Remove expired timestamps
const cutoff = Date.now() - this.windowMs;
this.timestamps = this.timestamps.filter(t => t > cutoff);
if (this.timestamps.length < this.maxRequests) {
this.timestamps.push(Date.now());
return true;
}
// Wait until the oldest request exits the window
const waitMs = Math.min(
this.timestamps[0] + this.windowMs - Date.now() + 10,
deadline - Date.now()
);
if (waitMs > 0) await new Promise(r => setTimeout(r, waitMs));
}
return false;
}
}
// Allow 20 solves per 5 minutes
const limiter = new SlidingWindowLimiter(20, 5 * 60 * 1000);
async function solveRateLimited(sitekey, pageurl) {
const acquired = await limiter.acquire(60000);
if (!acquired) throw new Error('Rate limit exceeded');
const submit = await axios.get('https://ocr.captchaai.com/in.php', {
params: {
key: API_KEY, method: 'userrecaptcha',
googlekey: sitekey, pageurl, json: '1',
},
});
if (submit.data.status !== 1) throw new Error(submit.data.request);
await new Promise(r => setTimeout(r, 15000));
for (let i = 0; i < 25; i++) {
const poll = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: API_KEY, action: 'get', id: submit.data.request, 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');
}
Patrón 3: Limitador basado en el presupuesto
Establezca un presupuesto de costos diario y deténgalo cuando lo alcance:
# budget_limiter.py
import os
import time
from datetime import date
class BudgetLimiter:
"""Limit daily CAPTCHA spending."""
def __init__(self, daily_budget, cost_per_solve=0.003):
self.daily_budget = daily_budget
self.cost_per_solve = cost_per_solve
self.daily_spend = 0.0
self.current_date = date.today()
def can_solve(self):
"""Check if budget allows another solve."""
if date.today() != self.current_date:
self.daily_spend = 0.0
self.current_date = date.today()
return self.daily_spend + self.cost_per_solve <= self.daily_budget
def record_solve(self):
"""Record a successful solve against the budget."""
self.daily_spend += self.cost_per_solve
@property
def remaining_budget(self):
return max(0, self.daily_budget - self.daily_spend)
@property
def remaining_solves(self):
return int(self.remaining_budget / self.cost_per_solve)
# $5/day budget
budget = BudgetLimiter(daily_budget=5.00, cost_per_solve=0.003)
def solve_with_budget(sitekey, pageurl):
if not budget.can_solve():
raise Exception(
f"Daily budget exhausted. Remaining: ${budget.remaining_budget:.2f}"
)
# ... solve logic ...
token = "..." # actual solve
budget.record_solve()
return token
Elegir un patrón
| Patrón | Mejor para | Complejidad |
|---|---|---|
| Cubo de fichas | Control de velocidad suave con margen de ráfaga | Medio |
| ventana corredera | Recuento de solicitudes simples por ventana de tiempo | Bajo |
| Limitador de presupuesto | Control de costes por día/week/month | Bajo |
| Combinado (tarifa + presupuesto) | Sistemas de producción | Medio |
Solución de problemas
| Problema | causa | Solución |
|---|---|---|
| Todas las solicitudes en cola, ninguna en ejecución | Tarifa demasiado baja para la demanda | Aumentar la velocidad o el tamaño de la ventana |
| El limitador de presupuesto se reinicia al mediodía | Cambio o reinicio del reloj del sistema | Mantener el gasto diario en un archivo o base de datos |
| El cubo de fichas se drena en explosión | Capacidad demasiado pequeña para el flujo de trabajo | Aumentar parámetro de capacidad |
| El limitador de velocidad bloquea las solicitudes de sondeo | Limitador aplicado también a las consultas. | Limite solo las solicitudes de envío, no las consultas |
Preguntas frecuentes
¿Debo limitar la calificación de la solicitud de envío o de la solicitud de consulta?
Límite de tarifa solo para la solicitud enviar (in.php). El sondeo (res.php) debería ejecutarse libremente ya que no crea nuevas tareas ni cuesta dinero.
¿Cómo comparto los límites de tarifas entre varios trabajadores?
Utilice la limitación de velocidad respaldada por Redis. Bibliotecas como redis-rate-limiter (Python) o rate-limiter-flexible (Node.js) admiten la limitación de velocidad distribuida con operaciones atómicas.
¿Puede CaptchaAI decirme mi tasa de uso actual?
Utilice el punto final del saldo para realizar un seguimiento de los gastos. Para un uso detallado, implemente sus propios contadores como se muestra en esta guía.
Artículos relacionados
- Captchaai Api Rate Limiting 429 Respuestas
- Flujos de trabajo de resolución de Captcha de limitación de velocidad
Próximos pasos
Controle su tasa de resolución de CAPTCHA y su presupuesto.obtenga su clave API CaptchaAI.
Guías relacionadas:
- Límites de velocidad y limitación
- 10.000 tareas por hora
- Verificación de saldo y recarga automática