Решение reCAPTCHA Enterprise с Node.js

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

Используйте официальный JavaScript SDK solvethree в Node.js 22+. Настройте активный профиль сайта, укажите имя хоста и действие сайта и выполните решение через прокси. SDK возвращает токен и идентификационные данные браузера; ваше приложение отправляет их целевому сайту.

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

Установите SDK и настройте сайт

Установите официальный пакет напрямую с solvethree.com:

Установка SDK для Node.js
npm install https://solvethree.com/downloads/solvethree-sdk-0.1.0.tgz
  1. 1.

    Активируйте профиль сайта

    Настройте целевой сайт в консоли и убедитесь, что его профиль активен и доступен вашему рабочему пространству. Передача имени хоста и действия не создаёт профиль. См. настройку профиля сайта.

  2. 2.

    Настройте окружение сервера

    В окружении процесса Node.js задайте для SOLVETHREE_API_KEY API-ключ рабочего пространства, а для SOLVETHREE_PROXY — URL прокси. Храните API-ключ на сервере; не раскрывайте его в браузерном коде.

  3. 3.

    Подготовьте скрипт

    Сохраните следующий пример как solve.mjs. Замените accounts.example.com на настроенное имя хоста, а login — на фактическое действие reCAPTCHA на странице.

Запросите токен Enterprise

В site укажите имя хоста, а не URL страницы. По умолчанию reCAPTCHA использует enterprise-v3, поэтому в примере не требуется recaptchaType. Не добавляйте type или url. Запрос должен содержать ровно одно из полей proxy или proxyCandidates; в этом примере используется один прокси.

Node.js · solve.mjs
import { randomUUID } from 'node:crypto';
import { Solvethree, SolvethreeError, TaskFailedError } from '@solvethree/sdk';

const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const request = {
  site: 'accounts.example.com', // Use your configured hostname.
  action: 'login',              // Use the page's actual action.
  proxy: process.env.SOLVETHREE_PROXY,
  requestId: randomUUID(),
};
let result;
try {
  result = await client.solve(request, { timeoutMs: 180_000 });
} catch (error) {
  if (error instanceof TaskFailedError) {
    throw new Error(`Task failed: ${error.errorCode}`);
  }
  if (error instanceof SolvethreeError) {
    // Save these IDs; use them to recover the existing task.
    console.error({ requestId: error.requestId, taskId: error.taskId });
  }
  throw error;
}
const { token, userAgent, secChUa } = result.solution;
console.log('Ready task:', result.id); // Keep solution credentials private.

После настройки переменных окружения запустите скрипт с помощью Node.js. solve создаёт задачу один раз и опрашивает её до готовности или возникновения исключения. Тайм-аут 180,000 мс ограничивает время ожидания клиента.

Возвращаемые поля имеют разное назначение:

  • result.id идентифицирует задачу. Это не токен CAPTCHA.
  • result.solution.token — значение для отправки в поле CAPTCHA приложения.
  • result.solution.userAgent и result.solution.secChUa — идентификационные данные браузера, которые нужно использовать с этим токеном.

Не раскрывайте значения решения. Если вам нужно восстановление после перезапуска процесса, сохраните requestId и точные входные данные задачи перед вызовом solve, обеспечив защиту всех учётных данных прокси.

Отправьте через тот же прокси

Продолжите выполнение в том же скрипте после возврата из solve. В этом примере используется undici, который нужно установить отдельно, как описано в комментарии. Пример отправляет токен через request.proxy и использует оба полученных поля идентификационных данных браузера.

Node.js undici · применение готового решения
// Continue after client.solve(). Install undici separately: npm install undici@7.
import { fetch, ProxyAgent } from 'undici';

const dispatcher = new ProxyAgent(request.proxy);
try {
  // Replace the URL and form fields with your application's contract.
  const response = await fetch('https://accounts.example.com/login', {
    method: 'POST',
    dispatcher,
    redirect: 'manual',
    headers: {
      'user-agent': result.solution.userAgent,
      'sec-ch-ua': result.solution.secChUa,
    },
    body: new URLSearchParams({
      'g-recaptcha-response': result.solution.token,
    }),
    signal: AbortSignal.timeout(30_000),
  });
  console.log('Application HTTP status:', response.status);
  await response.arrayBuffer();
} finally {
  await dispatcher.close();
}

Замените URL и поля формы в соответствии с требованиями вашего приложения. В примере передаётся только g-recaptcha-response; добавьте все остальные поля и данные сессии, необходимые приложению. Целевой запрос должен соответствовать сайту и действию, для которых выполнялось решение.

Поскольку запрос на решение использует один прокси, повторное использование request.proxy сохраняет отправку через этот прокси. Если вы измените запрос на использование proxyCandidates, выберите успешный прокси с помощью функции SDK successfulProxy.

Готовая задача означает, что решение сгенерировано, а не что целевой сайт принял запрос вашего приложения. Проверьте ответ целевого сайта на фактический признак успеха: вывода HTTP-статуса недостаточно. О диагностике отклонений см. готовый токен отклонён.

Обрабатывайте сбои и восстанавливайте прерванные запросы

Пример решения отделяет окончательные сбои задач от других ошибок SDK. Сохраняйте это различие: неудачная задача и неудачный HTTP-запрос требуют разной обработки.

solve вызывает TaskFailedError

Исключение содержит errorCode и taskId. Вызовите getTask(taskId), если вам нужен полный ответ по неудачной задаче, включая текст ошибки.

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

SolvethreeError содержит taskId

У SDK есть ID существующей задачи.

Попробуйте: Возобновите опрос с помощью getTask. Продолжайте при pending или solving, используйте решение только при ready и остановитесь при failed.

Создание прервано, и доступен только requestId

Тайм-аут соединения не доказывает, что задача не была создана.

Попробуйте: Восстановите задачу через createTask с идентичными входными данными и тем же requestId. Повторное использование этого ID с другими входными данными вызывает конфликт.

API отклоняет HTTP-запрос

Проверьте HTTP-статус, доступный в ApiError, вместо того чтобы трактовать ответ как готовую или неудачную задачу.

Попробуйте: Устраните HTTP-ошибку перед обработкой данных успешного ответа. Не считайте, что любой сбой вызван недостатком средств.

В примере при каждом запуске программы генерируется новый requestId. Повторный запуск без изменений — не восстановление: используйте сохранённый запрос и ID. SDK никогда не повторяет создание задачи автоматически; при временных сбоях опроса он учитывает Retry-After в пределах срока ожидания решения.

Подробнее о явном опросе и настройках ожидания см. в разделе опрос задач и тайм-ауты.

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

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

Создать рабочее пространство
Решение reCAPTCHA Enterprise с Node.js · solvethree