Решайте несколько CAPTCHA в Python и Node.js

Автор: solvethree3 мин на чтение

Ограничивайте число активных решений, а не только число запускаемых запросов. Примеры ниже выполняют восемь независимых задач reCAPTCHA Enterprise, поддерживая не более четырёх активных решений одновременно и обрабатывая каждый результат по мере готовности.

Четыре — пример настройки параллелизма, а не предел мощности solvethree. Выберите ограничение с учётом того, насколько быстро ваше приложение может использовать возвращённые решения.

На этой странице

Подготовьте SDK и входные данные задач

Используйте Python 3.10+ или Node.js 22+. Установите официальный SDK по URL загрузки из документации; используйте прямую загрузку пакета. Храните API-ключ рабочего пространства на сервере.

  • Задайте SOLVETHREE_API_KEY и SOLVETHREE_PROXY в окружении сервера.
  • Замените accounts.example.com и login на имя хоста и действие для вашего целевого сайта. У сайта уже должен быть активный профиль, доступный вашему рабочему пространству; отправка имени хоста не создаёт его.
  • Считайте каждую запись в jobs отдельной логической задачей. Для наглядности в примерах повторяются одинаковые сайт, действие и прокси, но каждой задаче назначается отдельный requestId.
  • Не меняйте входные данные задачи при восстановлении. Для нового независимого решения нужен новый ID; для восстановления прерванного решения — исходный ID и идентичные входные данные.

Запустите пакет с ограниченным параллелизмом

Python · четыре одновременных решения
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__)

Здесь Python нужны потоки, поскольку `Solvethree` работает синхронно. Каждый вызов solve создаёт задачу и ждёт готового результата либо выбрасывает исключение. Нативного асинхронного клиента нет, поэтому прямой вызов внутри асинхронной функции всё равно заблокирует поток её цикла событий. В примере используются четыре обработчика в пуле потоков, каждый со своим клиентом, а завершённые объекты Future обрабатываются без ожидания всего пакета.

Node.js ограничивает параллелизм с помощью четырёх рабочих промисов. Каждый обработчик ожидает завершения одного решения, прежде чем взять следующее задание. Promise.all ожидает эти обработчики; он не запускает все задания одновременно. Напротив, прямое отображение неограниченного списка заданий на вызовы solve немедленно запускает весь список и не даёт полезного ограничения параллелизма.

Оба примера перехватывают ошибки отдельно для каждой задачи, поэтому один сбой решения не останавливает остальные задания. Тайм-аут в 180 секунд применяется к каждому вызову solve, а не ко всему пакету.

Используйте каждый готовый результат сразу

Перед запуском реального пакета замените комментарий в ветке успешного выполнения на отправку данных целевому сайту. Выведенный ID идентифицирует задачу; это не токен reCAPTCHA. Отправьте solution.token вместе с возвращёнными userAgent и secChUa, используя тот же прокси, который был указан для этой задачи.

Не собирайте все токены и не ждите самого медленного решения, прежде чем использовать их. Обрабатывайте каждый готовый результат там, где он поступает. SDK решает CAPTCHA, но не отправляет решение целевому сайту, а готовая задача не доказывает, что целевой сайт принял последующий запрос.

Восстанавливайте одну прерванную задачу, а не весь пакет

Для краткости схемы обработчиков примеры выводят имена классов ошибок. В интеграции сохраняйте затронутое задание и идентификаторы восстановления, доступные в ошибках SDK: Python использует request_id и task_id; JavaScript — requestId и taskId.

При решении возникает тайм-аут или теряется соединение.

Проверьте, содержит ли ошибка ID задачи или ID запроса. Задача на сервере может по-прежнему существовать.

Попробуйте: Если ID задачи известен, возобновите опрос через GET. В противном случае восстановите создание, повторив идентичные входные данные с тем же идентификатором запроса.

SDK выбрасывает TaskFailedError.

Проверьте errorCode и error завершённой задачи.

Попробуйте: Прекратите опрос этой задачи и устраните указанную причину, прежде чем запускать новое решение. Не повторяйте вслепую запросы с неизменёнными некорректными входными данными.

Повторный запуск любого из примеров генерирует новые идентификаторы запросов и запускает новые логические задачи; это не восстановление. Оба SDK не повторяют создание задач автоматически, поэтому сохраняйте достаточно информации, чтобы восстановить только прерванное задание, а не отправлять повторно уже успешно выполненную работу.

Запустите первую задачу.

Начните с $5 на балансе рабочего пространства.

Создать рабочее пространство
Решайте несколько CAPTCHA в Python и Node.js · solvethree