Resuelve varios CAPTCHA en Python y Node.js
Limita el número de resoluciones activas, no solo el número de solicitudes que inicias. Los siguientes ejemplos ejecutan ocho tareas independientes de reCAPTCHA Enterprise con un máximo de cuatro resoluciones activas a la vez y procesan cada resultado en cuanto termina.
Cuatro es un valor de concurrencia de ejemplo, no un límite de capacidad de solvethree. Elige un límite acorde con la rapidez con la que tu aplicación pueda usar las soluciones devueltas.
En esta página
Prepara el SDK y los datos de entrada de las tareas
Usa Python 3.10+ o Node.js 22+. Instala el SDK oficial desde la URL de descarga de la documentación; usa la descarga directa del paquete. Mantén la clave de API del espacio de trabajo en el servidor.
- Configura
SOLVETHREE_API_KEYySOLVETHREE_PROXYen el entorno del servidor. - Sustituye
accounts.example.comyloginpor el nombre de host y la acción de destino. El sitio ya debe tener un perfil activo disponible para tu espacio de trabajo; enviar un nombre de host no lo crea. - Trata cada entrada de
jobscomo una tarea lógica independiente. Los ejemplos repiten el mismo sitio, acción y proxy para facilitar la lectura del lote, pero asignan unrequestIddistinto a cada tarea. - Mantén los datos de entrada de cada tarea sin cambios durante la recuperación. Una nueva resolución independiente necesita un ID nuevo; recuperar una resolución interrumpida requiere el ID original y datos de entrada idénticos.
Ejecuta un lote con concurrencia limitada
import os
from concurrent.futures import ThreadPoolExecutor, as_completed
from uuid import uuid4
from solvethree import Solvethree
# Each worker gets its own synchronous client.
def solve_one(job):
client = Solvethree(os.environ["SOLVETHREE_API_KEY"])
return client.solve({**job, "requestId": str(uuid4())}, timeout=180)
jobs = [
{"site": "accounts.example.com", "action": "login", "proxy": os.environ["SOLVETHREE_PROXY"]}
for _ in range(8)
]
with ThreadPoolExecutor(max_workers=4) as pool:
futures = [pool.submit(solve_one, job) for job in jobs]
for future in as_completed(futures):
try:
result = future.result()
print("Ready task:", result["id"])
# Submit this solution promptly; don't wait for the whole batch.
except Exception as error:
print("One task failed:", type(error).__name__)import { randomUUID } from 'node:crypto';
import { Solvethree } from '@solvethree/sdk';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const jobs = Array.from({ length: 8 }, () => ({
site: 'accounts.example.com', action: 'login',
proxy: process.env.SOLVETHREE_PROXY, requestId: randomUUID(),
}));
let next = 0;
async function worker() {
while (next < jobs.length) {
const job = jobs[next++];
try {
const result = await client.solve(job, { timeoutMs: 180_000 });
console.log('Ready task:', result.id);
// Submit this solution promptly, before taking another job.
} catch (error) {
console.error('One task failed:', error.constructor.name);
}
}
}
await Promise.all(Array.from({ length: Math.min(4, jobs.length) }, worker));Python necesita hilos aquí porque `Solvethree` es síncrono. Cada llamada a solve crea una tarea y espera un resultado listo o lanza una excepción. No hay un cliente asíncrono nativo, por lo que llamarlo directamente dentro de una función asíncrona seguiría bloqueando el hilo del bucle de eventos de esa función. El ejemplo usa cuatro trabajadores de un grupo de hilos, cada uno con su propio cliente, y procesa los futuros completados sin esperar a que termine todo el lote.
Node.js limita la concurrencia mediante cuatro promesas de trabajo. Cada trabajador espera a que termine una resolución antes de tomar otro trabajo. Promise.all espera a esos trabajadores; no inicia todos los trabajos a la vez. En cambio, convertir directamente una lista de trabajos sin límite en llamadas a solve inicia toda la lista de inmediato y no proporciona un límite de concurrencia útil.
Ambos ejemplos capturan los errores por tarea para que una resolución fallida no detenga los demás trabajos. El tiempo de espera de 180 segundos se aplica a cada llamada a solve, no a todo el lote.
Usa cada resultado listo de inmediato
Sustituye el comentario de la ruta de éxito por el envío al sitio de destino antes de ejecutar un lote real. El ID mostrado identifica la tarea; no es el token reCAPTCHA. Envía solution.token con los valores devueltos de userAgent y secChUa, usando el mismo proxy proporcionado para esa tarea.
No acumules todos los tokens ni esperes a la resolución más lenta para usarlos. Procesa cada resultado listo en cuanto llegue. El SDK resuelve el CAPTCHA; no envía la solución al sitio de destino, y una tarea lista no demuestra que el sitio de destino haya aceptado la solicitud posterior.
Recupera una tarea interrumpida, no todo el lote
Los ejemplos muestran los nombres de las clases de error para mantener breve el patrón de trabajadores. En una integración, conserva el trabajo afectado y los ID de recuperación que exponen los errores del SDK: Python usa request_id y task_id; JavaScript usa requestId y taskId.
- Una resolución agota su tiempo de espera o pierde la conexión.
Comprueba si el error incluye un ID de tarea o de solicitud. Es posible que la tarea remota aún exista.
Prueba esto: Reanuda las consultas GET periódicas si conoces el ID de tarea. De lo contrario, recupera la creación volviendo a enviar datos de entrada idénticos con el mismo ID de solicitud.
- El SDK lanza TaskFailedError.
Inspecciona errorCode y error de la tarea en estado terminal.
Prueba esto: Deja de consultar esa tarea y corrige la causa indicada antes de iniciar otra resolución. No reintentes a ciegas con datos de entrada no válidos sin modificarlos.
Volver a ejecutar cualquiera de los ejemplos genera nuevos ID de solicitud e inicia nuevas tareas lógicas; no es una recuperación. Ninguno de los SDK reintenta automáticamente la creación de tareas, así que conserva información suficiente para recuperar solo el trabajo interrumpido en lugar de volver a enviar trabajo ya completado correctamente.
Fuentes y referencia de la API
Ejecuta tu primera tarea.
Empieza con $5 de crédito en tu espacio de trabajo.