Перейти к основному содержимому
Возникают проблемы с получением токена?
Свяжитесь с поддержкой

Altcha - Alternative CAPTCHA

Примеры заданий

Также существует невидимая капча (Invisible Captcha), которая не имеет видимого интерфейса на странице и не требует каких-либо действий пользователя — проверка выполняется в фоновом режиме.

Внимание!

CapMonster Cloud по умолчанию работает через встроенные прокси — они уже включены в стоимость. Указывать собственные прокси требуется только в тех случаях, когда сайт не принимает токен или доступ к встроенным сервисам ограничен.

Если прокси с авторизацией по IP, то необходимо добавить адрес 65.21.190.34 в белый список.

Параметры запроса

type<string>required

CustomTask


class<string>required

altcha


websiteURL<string>required

Адрес основной страницы, на которой находится altcha.


websiteKey<string>required

Для этой задачи допустимо отправлять пустую строку.


challenge (внутри metadata)<string>required

Уникальный идентификатор задачи, полученный с веб-страницы.


iterations (внутри metadata)<string>required

Количество итераций или максимальное число для вычислений.

Важно: параметр iterations соответствует значению maxnumber!


salt (внутри metadata)<string>required

Полученный с сайта salt, используемый для генерации хэшей.

Важно: отправляйте значение поля salt целиком! Если сайт присылает, например, такое значение:

"salt":"46d5b1c8871e5152d902ee3f?edk=1493462145de1ce33a52fb569b27a364&codeChallenge=464Cjs7PbiJJhJZ_ReJ-y9UGGDndcpsnP6vS8x1nEJyTkhjQkJyL2jcnYEuMKcrG&expires=1761048664"

— скопируйте и передайте его в запросе ровно в таком виде, включая все символы и параметры (edk, codeChallenge и т.д.).


signature (внутри metadata)<string>required

Цифровая подпись запроса.


userAgent<string>optional

User-Agent браузера.
Передавайте только актуальный UA от ОС Windows. Сейчас таковым является: userAgentPlaceholder


proxyType<string>optional

http - обычный http/https прокси;
https - попробуйте эту опцию, только если "http" не работает (требуется для некоторых кастомных прокси);
socks4 - socks4 прокси;
socks5 - socks5 прокси.


proxyAddress<string>optional

IP адрес прокси IPv4/IPv6. Не допускается:

  • использование прозрачных прокси (там где можно видеть IP клиента);
  • использование прокси на локальных машинах.


proxyPort<integer>optional

Порт прокси.


proxyLogin<string>optional

Логин прокси-сервера.


proxyPassword<string>optional

Пароль прокси-сервера.


Метод создания задачи

POST
https://api.capmonster.cloud/createTask

Запрос

{
"clientKey": "API_KEY",
"task": {
"type": "CustomTask",
"class": "altcha",
"websiteURL": "https://example.com",
"websiteKey": "",
"userAgent": "userAgentPlaceholder",
"metadata": {
"challenge": "3dd28253be6cc0c54d95f7f98c517e68744597cc6e66109619d1ac975c39181c",
"iterations": "5000",
"salt":"46d5b1c8871e5152d902ee3f?edk=1493462145de1ce33a52fb569b27a364&codeChallenge=464Cjs7PbiJJhJZ_ReJ-y9UGGDndcpsnP6vS8x1nEJyTkhjQkJyL2jcnYEuMKcrG&expires=1761048664",
"signature": "4b1cf0e0be0f4e5247e50b0f9a449830f1fbca44c32ff94bc080146815f31a18"
}
}
}

Ответ

{
"errorId": 0,
"taskId": 407533072
}

Метод получения результата задачи

Используйте метод getTaskResult, чтобы получить решение Altcha.

POST
https://api.capmonster.cloud/getTaskResult

Запрос

{
"clientKey": "API_KEY",
"taskId": 407533072
}

Ответ

{
"errorId": 0,
"status": "ready",
"solution": {
"number": 4883
}
}

Как найти все нужные параметры для создания задачи на решение

Ниже приведены примеры извлечения параметров Altcha, необходимых для отправки задачи на решение в CapMonster Cloud. Обратите внимание, что реализация капчи может отличаться на разных сайтах, поэтому способы получения параметров могут варьироваться.

  1. В браузере откройте страницу с Altcha, запустите DevTools (F12 или Ctrl+Shift+I), затем перейдите на вкладку Network.

  2. Нажмите на чекбокс капчи и пройдите её вручную. В поле поиска в Network введите любое название параметра (например, "algorithm").

  3. Среди найденных элементов найдите запрос, в котором содержится JSON с параметрами.

  4. Кликните по запросу и при необходимости перейдите на вкладку Response, чтобы увидеть данные, возвращённые сервером.

  5. Скопируйте параметры — эти значения нужно использовать для создания задачи в CapMonster Cloud.

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

После получения необходимых параметров их нужно передать в объект metadata при создании задачи в CapMonster Cloud. Пример структуры:

metadata: {
challenge: "<значение challenge>",
iterations: "<значение maxnumber>", // необходимо оформлять в кавычках, как и остальные параметры
salt: "<значение salt>",
signature: "<значение signature>",
}

Также для получения всех параметров можно воспользоваться приведёнными ниже примерами кода:

Пример GET-запроса

Делает HTTP GET-запрос к указанному URL и выводит полученный ответ в консоль.

const url = 'https://example-portal.mysite.rs.gov.br/Altcha/Example'; // API-эндпоинт, откуда извлекаются параметры капчи

fetch(url, { method: 'GET' })
.then(res => res.text())
.then(data => console.log('Response:', data))
.catch(err => console.error(err));
Перехват параметров

Скрипт для браузера, который переопределяет fetch и XMLHttpRequest, чтобы автоматически отслеживать сетевые запросы и извлекать ключевые параметры капчи Altcha. На странице с капчей вставьте данный скрипт в консоль браузера и активируйте капчу — необходимые параметры будут автоматически выведены в консоль.

(function() {
const keywords = ['algorithm','challenge','maxnumber','salt','signature'];
const foundParams = {};

const intercept = (url, body, text) => {
keywords.forEach(key => {
if ((url && url.includes(key)) || (body && body.includes(key)) || (text && text.includes(key))) {
foundParams[key] = foundParams[key] || [];
if (url?.includes(key)) foundParams[key].push(url);
if (body?.includes(key)) foundParams[key].push(body);
if (text?.includes(key)) foundParams[key].push(text);
}
});
if (Object.keys(foundParams).length) console.log('Found parameters:', foundParams);
};

const originalFetch = window.fetch;
window.fetch = async (...args) => {
const [resource, config] = args;
const url = typeof resource === 'string' ? resource : resource.url;
const body = config?.body;
const response = await originalFetch.apply(this, args);
try {
const text = await response.clone().text();
intercept(url, body, text);
} catch {}
return response;
};

const originalOpen = XMLHttpRequest.prototype.open;
const originalSend = XMLHttpRequest.prototype.send;

XMLHttpRequest.prototype.open = function(method, url, ...rest) {
this._url = url;
return originalOpen.call(this, method, url, ...rest);
};

XMLHttpRequest.prototype.send = function(body) {
this.addEventListener('load', () => intercept(this._url, body, this.responseText));
return originalSend.call(this, body);
};
})();

Пример автоматического решения Altcha на Node.js и Playwright

В некоторых случаях для подтверждения решения достаточно отправить только параметр number. Однако иногда сайт требует все параметры, зашифрованные в формате base64.

Например:

Если декодировать это значение, на выходе мы получим JSON-объект, содержащий данные, используемые для валидации капчи:

{
"algorithm": "SHA-256",
"challenge": "86d178e154a5d04665710897b7bfc269d86407830d3a49dad3a3e027f6a824a6",
"number": 92199,
"salt": "f8ec36f9d615aa2c67c7ea29e?expires=1759147489",
"signature": "29a57a68dd2b1de8cba74b104c38de8fc860f8dd5b5eacd04755dcff7eb7ee8f",
"took": 1520
}

В ответе от CapMonster Cloud возвращаются отдельно number и полный набор параметров, уже закодированный в base64 (включая number).

В приведённом примере подтверждение решения выполняется с помощью токена, содержащего полный набор параметров. Если же вам требуется отправлять только number, необходимо изменить логику подтверждения решения соответствующим образом.

Показать пример кода
const { chromium } = require("playwright");

// Замените значения на свои:
// - API_KEY → ваш ключ CapMonster Cloud
// - ALTCHA_PAGE → адрес страницы с Altcha
const API_KEY = "your_capmonster_cloud_api_key";
const ALTCHA_PAGE = "https://url_with_altcha";

(async () => {
const browser = await chromium.launch({ headless: false, devtools: true });
const context = await browser.newContext();
const page = await context.newPage();

await page.route("**/*", (route) => {
const url = route.request().url();
if (url.includes("api.capmonster.cloud")) return route.abort();
return route.continue();
});

let challengeResp = null; // Переменная для хранения challenge Altcha
page.on("response", async (response) => {
try {
if (response.url().includes("/Altcha/GerarDesafio")) {
challengeResp = await response.json(); // Получаем JSON с параметрами challenge
console.log("Captured /Altcha/GerarDesafio:", challengeResp);
}
} catch {}
});

await page.goto(ALTCHA_PAGE, { waitUntil: "networkidle" }); // Переход на страницу с Altcha

try {
await page.waitForSelector("altcha-widget input[type='checkbox']", { timeout: 10000 });
await page.click("altcha-widget input[type='checkbox']");
} catch {
const widgetHandle = await page.$("altcha-widget");
if (widgetHandle) await widgetHandle.click(); // Если стандартный селектор не найден
}

// Ожидание получения challenge
const start = Date.now();
while (!challengeResp && Date.now() - start < 30000) {
await new Promise((r) => setTimeout(r, 300));
}
if (!challengeResp) {
console.error("Failed to capture /Altcha/GerarDesafio.");
await browser.close();
return;
}

const { challenge, salt, signature, maxnumbers } = challengeResp;

// Формирование тела запроса для создания задачи CapMonster Cloud
const createTaskBody = {
clientKey: API_KEY,
task: {
type: "CustomTask",
class: "altcha",
websiteURL: ALTCHA_PAGE,
websiteKey: "",
userAgent:
"userAgentPlaceholder",
metadata: {
challenge,
iterations: maxnumbers,
salt,
signature,
},
},
};

// Создание задачи на CapMonster Cloud
const taskResp = await fetch("https://api.capmonster.cloud/createTask", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(createTaskBody),
}).then((r) => r.json());

console.log("CreateTask response:", taskResp);
if (!taskResp || !taskResp.taskId) {
console.error("CreateTask failed:", taskResp);
await browser.close();
return;
}

const taskId = taskResp.taskId;

// Ожидание решения задачи
let fullSolution = null;
const maxPollMs = 120000;
const pollStart = Date.now();
while (Date.now() - pollStart < maxPollMs) {
const res = await fetch("https://api.capmonster.cloud/getTaskResult", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ clientKey: API_KEY, taskId }),
}).then((r) => r.json());

if (res.status === "ready") {
fullSolution = res.solution;
console.log("Full solution from CapMonster:", fullSolution);
break;
}
await new Promise((r) => setTimeout(r, 3000));
}

if (!fullSolution) {
console.error("Solution was not received within the allocated time.");
await browser.close();
return;
}

// Извлечение токена из решения
const token =
(fullSolution && fullSolution.data && fullSolution.data.token) ||
fullSolution.token ||
(fullSolution && fullSolution.data) ||
null;

if (!token) {
console.error("Token not found in CapMonster response:", fullSolution);
await browser.close();
return;
}

// Внедрение токена на страницу
await page.evaluate((tokenValue) => {
const cpv = document.querySelector("#captchaParaValidar");
if (cpv) {
cpv.value = tokenValue;
} else {
const created = document.createElement("input");
created.type = "hidden";
created.id = "captchaParaValidar";
created.name = "captchaParaValidar";
created.value = tokenValue;
(document.querySelector("form") || document.body).appendChild(created);
}

let alt = document.querySelector('input[name="altcha"]');
if (alt) {
alt.value = tokenValue;
} else {
const created2 = document.createElement("input");
created2.type = "hidden";
created2.name = "altcha";
created2.value = tokenValue;
(document.querySelector("form") || document.body).appendChild(created2);
}

const widget = document.querySelector("altcha-widget");
if (widget) {
widget.setAttribute("data-state", "verified");
const checkbox = widget.querySelector("input[type='checkbox']");
if (checkbox) {
checkbox.checked = true;
checkbox.dispatchEvent(new Event("change", { bubbles: true }));
}
const label = widget.querySelector(".altcha-label");
if (label) label.textContent = "Verified";
}
}, token);

console.log("Token injected:", token);
})();