К содержимому

Документация

Captcha: явные задания в JavaScript

Через ctx.captcha() можно узнать параметры задания, оценить стоимость, явно отправить его и получить ответ. Этот API не открывает сайт, не обнаруживает новую CAPTCHA, не заполняет форму и не применяет ответ в браузере. Тип задания определяет входные поля и формат ответа. В преобразованиях выгрузки, где запрещены host calls, эти методы недоступны.

Контракт одинаков в облаке и на собственном агенте. В сценарии не нужны внешний аккаунт, ключ сервиса или платёжный токен. Работа учитывается по тарифу и балансу пространства сайта. Агенту требуется связь с Akmelo; без облака эти операции недоступны.

Перед отправкой

Начните с types() и describe(type): они читают актуальный каталог без платного задания. После подготовки полей вызовите quote(task). Задание создаёт только createTask(); в Python используется create_task(). Оценка стоимости сама по себе не резервирует деньги и не фиксирует будущую цену. Для создания CAPTCHA должна быть разрешена настройками сайта и платформы.

Не отправляйте пароли, cookies авторизации, персональные данные и постороннее содержимое страницы. Передавайте только поля из describe(type). Произвольные адреса API, выбор внешнего сервиса, ключи и callback не являются настройками задания. Разным типам нужны разные данные; их нельзя просто переименовать друг в друга.

В GridTask.previousId передавайте наш taskId предыдущего готового GridTask того же сайта и пространства, а на агенте — также того же агента. Платформа сама разрешает внутреннюю ссылку; внешний идентификатор или чужое задание отклоняются до отправки.

Методы

types

await ctx.captcha().types()

Возвращает {types: [...], languages: [...], unit: 1000000}. Каждый элемент каталога описывает доступный тип; languages содержит допустимые коды языковых пулов. Список актуален для этой установки: не храните собственную копию названий как источник истины. Включённость тарифа и остатки проверяются отдельно при создании.

describe

await ctx.captcha().describe('ImageToTextTask')

Возвращает описание одного типа: type, name, kind, parameters, solution и ценовую информацию. parameters содержит допустимые поля, типы, обязательность и пределы; solution описывает форму ответа. Неизвестный тип отклоняется. Например, ImageToTextTask принимает base64 в body, а AudioTask — аудио в body и язык аудио в lang (это отдельное поле от options.languagePool); точные ограничения читайте в схеме.

В некоторых описаниях есть required_any: кроме обычных обязательных полей нужно заполнить хотя бы один полный альтернативный набор. requirements описывает условные требования, например для разных версий задания. Одного списка необязательных полей недостаточно для правильной отправки. В price значение quoted: false означает технический резерв вместо подтверждённого диапазона цены; available говорит о доступности цены, а не об успешном доступе к сайту.

quote

await ctx.captcha().quote(task)

Проверяет поля и возвращает {minimum, maximum, unit: 1000000}. Суммы в микро₽: 1 000 000 единиц = 1 ₽. minimum: null означает, что нижняя граница не определена; это не нулевая цена. maximum — верхняя оценка для предварительного резерва. Включённые в тариф задания и разрешённые дополнительные расходы всё равно проверяются сервером.

createTask

await ctx.captcha().createTask(task, options = {})

Создаёт явное задание. Результат: {taskId, status}, где taskId — UUID платформы, при новой отправке статус processing либо uncertain. Повтор с тем же ключом запроса может вернуть уже готовое или неуспешное состояние ready/failed. Не передавайте сюда идентификатор задания из другой системы. Неизвестные типы, поля и некорректные значения отклоняются до отправки. Возврат uncertain означает неопределённость отправки: сохраните идентификатор и проверяйте его, а не создавайте новый платный запрос.

getTaskResult

await ctx.captcha().getTaskResult(taskId)

Читает состояние существующего задания, не создавая новое. Возвращает taskId, status, unit и, когда доступны, solution, cost, error. Формат solution зависит от типа: это JSON-значение, в том числе объект, массив, строка, число, логическое значение или null. Не считайте наличие текстового поля обязательным: ответ может содержать координаты, угол, токен или другую описанную структуру. Сверяйтесь с JSON Schema solution в описании типа. При ошибке используйте безопасное поле error для диагностики.

waitForResult

await ctx.captcha().waitForResult(taskId, timeoutMs = 120000)

Ожидает результат существующего задания. timeoutMs от 0 до 120000; 0 даёт однократную проверку. По окончании ожидания возвращается последнее состояние, в том числе processing или uncertain. Это не отменяет задание и не создаёт повтор. Остановка или общий срок прогона прерывают ожидание ошибкой. Чтобы продолжить позже, сохраните taskId и вызовите получение результата снова.

reportCorrect

await ctx.captcha().reportCorrect(taskId)

Отправляет обратную связь об уже проверенном правильном ответе. Возвращает {taskId, accepted}. accepted: true означает приём отзыва, а не автоматическую проверку сайта. Не отправляйте положительный отзыв просто потому, что статус стал ready.

reportIncorrect

await ctx.captcha().reportIncorrect(taskId)

Отправляет обратную связь об уже проверенном неправильном ответе. Возвращает {taskId, accepted}. Приём отзыва не обещает возврат денег, не отменяет задание и не запускает новое. Отказ сайта по другой причине не доказывает ошибку результата CAPTCHA.

Параметры создания

Ключи options одинаковы во всех языках; snake_case в Python относится к названиям методов.

Поле Значение Для чего
requestId 1–128 символов: A–Z, a–z, 0–9, ., _, :, - Постоянный ключ идемпотентности одной логической отправки в пределах того же прогона. При её повторе используйте тот же ключ; для действительно нового входа нужен новый. В новом прогоне прежний ключ не переиспользует старую отправку: читайте сохранённый taskId, а не создавайте её снова.
language ru или en Короткая форма выбора языкового пула.
languagePool Код из types().languages, например zh Языковой пул инструкций задания. Это не язык сайта; не сочетайте его с отличающимся значением language.
maxCost Неотрицательное целое в микро₽ Ваш потолок на задание. Если системный резерв выше него, отправка отклоняется. Параметр не меняет цену задания.

Статусы и оплата

Статус Что делать
processing Ожидать по этому идентификатору.
ready Читать ответ и отдельно проверять его применение.
failed Разобраться в ошибке, не запускать бесконечный повтор.
uncertain Отправка либо её итог не подтверждены. Повторно проверить этот же идентификатор.

Готовый ответ может быть платным, даже если сайт его отверг. Действуют обычные для пространства количество CAPTCHA в тарифе, баланс, резервы и пределы стоимости. Если поле cost есть, это сумма списания пространства в микро₽, а не отдельный счёт другого сервиса. Оценка не равна итоговому списанию; неиспользованный резерв освобождается после сверки. Остановка прогона либо таймаут ожидания не обещают отмену или возврат.

Идентификатор доступен только тому же сайту и пространству. Агент читает только задания своего агента. Другой прогон того же разрешённого сайта может прочитать существующее задание; знание UUID не даёт доступа. Ответ хранится 24 часа. После истечения срока ready может вернуться без solution и с error: result_expired; сохраняйте нужный результат обработки, а не материал для повторной авторизации.

Полный пример со своей фикстурой

Подготовьте небольшую картинку с известным текстом и передайте только её base64 в параметре прогона fixture_image_base64, без URL и префикса data-URL. По умолчанию пример только получает оценку: send_task=false. Устанавливайте send_task=true, только когда хотите отправить платное задание. При смене фикстуры меняйте ключ запроса. Проверка кода проверяет синтаксис и SDK, не отправляя задание.

async function run(ctx) {
  const captcha = ctx.captcha();
  const body = ctx.param('fixture_image_base64', '');
  if (!body) ctx.abort('Укажите base64 собственного тестового изображения');
  const task = { type: 'ImageToTextTask', body };
  const price = await captcha.quote(task);
  ctx.log('Максимальный резерв: ' + price.maximum + ' микро₽');
  if (!ctx.param('send_task', false)) return;
  const created = await captcha.createTask(task, {
    requestId: 'fixture-image-001',
    language: 'ru',
    maxCost: price.maximum,
  });
  const result = await captcha.waitForResult(created.taskId, 120000);
  const solution = result.solution;
  if (result.status === 'ready' && solution !== null &&
      typeof solution === 'object' && !Array.isArray(solution) &&
      typeof solution.text === 'string') {
    ctx.emit({ text: solution.text }, 'fixture-001');
  } else {
    ctx.log('Состояние задания: ' + result.status);
  }
}

Другие входные данные и ошибки

Для аудио сначала прочитайте describe("AudioTask"): передайте аудио base64 в body и документированное значение lang. Для остальных типов читайте их собственные параметры и схему ответа. Не отправляйте токеновое задание как картинку и не превращайте массив координат в строку. Некорректный base64, лишние поля, размер, отключённая функция, недостаточный бюджет и недоступный идентификатор — разные ошибки. Исправляйте причину; ожидание по имеющемуся UUID отличается от новой отправки.

Этот API не расширяет список типов, автоматически определяемых браузером. autoCaptcha=false (Python: auto_captcha=False) управляет автоматическим HTTP/браузерным режимом и не отключает явное создание. Чтобы исключить платные отправки, не вызывайте метод создания.

Руководство по CAPTCHA · Обзор API · Баланс и тариф