Resolva vários CAPTCHAs em Python e Node.js
Limite o número de resoluções ativas, não apenas o número de requisições que você inicia. Os exemplos abaixo executam oito tarefas independentes de reCAPTCHA Enterprise com no máximo quatro resoluções ativas ao mesmo tempo, tratando cada resultado assim que ele fica pronto.
Quatro é uma configuração de concorrência de exemplo, não um limite de capacidade do solvethree. Escolha um limite adequado à rapidez com que sua aplicação consegue usar as soluções retornadas.
Nesta página
Prepare o SDK e os dados de entrada das tarefas
Use Python 3.10+ ou Node.js 22+. Instale o SDK oficial pela URL de download na documentação; use o download direto do pacote. Mantenha a chave de API do espaço de trabalho no servidor.
- Defina
SOLVETHREE_API_KEYeSOLVETHREE_PROXYno ambiente do servidor. - Substitua
accounts.example.comeloginpelo nome de host e pela ação de destino. O site já deve ter um perfil ativo disponível para o seu espaço de trabalho; enviar um nome de host não cria um perfil. - Trate cada entrada em
jobscomo uma tarefa lógica separada. Os exemplos repetem o mesmo site, ação e proxy para facilitar a leitura do lote, mas atribuem umrequestIddistinto a cada tarefa. - Mantenha os dados de entrada de cada tarefa sem alterações durante a recuperação. Uma nova resolução independente precisa de um novo ID; recuperar uma resolução interrompida exige o ID original e dados de entrada idênticos.
Execute um lote com concorrência 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 precisa de threads aqui porque `Solvethree` é síncrono. Cada chamada a solve cria uma tarefa e espera por um resultado pronto ou lança uma exceção. Não há cliente assíncrono nativo, portanto chamá-lo diretamente dentro de uma função assíncrona ainda bloquearia a thread do loop de eventos dessa função. O exemplo usa quatro workers em um pool de threads, cada um com seu próprio cliente, e trata os futures concluídos sem esperar pelo lote inteiro.
Node.js limita a concorrência por meio de quatro promises de workers. Cada worker aguarda uma resolução antes de assumir outro trabalho. Promise.all espera por esses workers; ele não inicia todos os trabalhos ao mesmo tempo. Por outro lado, mapear uma lista de trabalhos sem limite diretamente para chamadas a solve inicia toda a lista imediatamente e não oferece um limite útil de concorrência.
Ambos os exemplos capturam erros por tarefa para que uma resolução com falha não interrompa os trabalhos restantes. O tempo limite de 180 segundos se aplica a cada chamada a solve, não ao lote inteiro.
Use cada resultado pronto imediatamente
Substitua o comentário no fluxo de sucesso pelo envio ao destino antes de executar um lote real. O ID impresso identifica a tarefa; ele não é o token reCAPTCHA. Envie solution.token com os valores retornados de userAgent e secChUa, usando o mesmo proxy fornecido para essa tarefa.
Não acumule todos os tokens nem espere pela resolução mais lenta antes de usá-los. Trate cada resultado pronto no ponto em que ele chega. O SDK resolve o CAPTCHA; ele não envia a solução ao destino, e uma tarefa pronta não comprova que o destino aceitou a requisição subsequente.
Recupere uma tarefa interrompida — não o lote inteiro
Os exemplos imprimem os nomes das classes de erro para manter o padrão de workers conciso. Em uma integração, guarde o trabalho afetado e os IDs de recuperação expostos pelos erros do SDK: Python usa request_id e task_id; JavaScript usa requestId e taskId.
- Uma resolução atinge o tempo limite ou perde a conexão.
Verifique se o erro contém um ID de tarefa ou de requisição. A tarefa remota ainda pode existir.
Experimente: Retome as consultas GET periódicas quando souber o ID da tarefa. Caso contrário, recupere a criação reenviando dados de entrada idênticos com o mesmo ID de requisição.
- O SDK lança TaskFailedError.
Verifique errorCode e error da tarefa em estado terminal.
Experimente: Pare de consultar essa tarefa e resolva a causa informada antes de iniciar outra resolução. Não tente novamente às cegas com os mesmos dados de entrada inválidos.
Executar novamente qualquer um dos exemplos gera novos IDs de requisição e inicia novas tarefas lógicas; isso não é recuperação. Ambos os SDKs evitam repetir automaticamente a criação de tarefas, portanto guarde informações suficientes para recuperar apenas o trabalho interrompido em vez de reenviar trabalhos concluídos com sucesso.
Fontes e referência da API
Execute sua primeira tarefa.
Comece com $5 em créditos no espaço de trabalho.