Типы капч
reCAPTCHA v2#
Типы RecaptchaV2TaskProxyless и RecaptchaV2Task.
| Параметр | Обязательный | Тип | Описание |
|---|---|---|---|
websiteURL |
да | string | Полный URL страницы, где размещена капча |
websiteKey |
да | string | Значение data-sitekey виджета reCAPTCHA |
isInvisible |
нет | bool | true для невидимой (invisible) reCAPTCHA. По умолчанию false |
recaptchaDataSValue |
нет | string | Значение параметра data-s, встречается на некоторых страницах Google (поиск, YouTube) |
userAgent |
нет | string | User-Agent, под которым решается капча; желательно передавать тот же, что использует ваш бот |
cookies |
нет | string | Cookies в формате name1=value1; name2=value2, если для решения важна сессия |
enterprisePayload |
нет | object | Дополнительные данные для reCAPTCHA v2 Enterprise, если используется enterprise-разметка |
Только для RecaptchaV2Task (решение через ваш прокси), дополнительно:
| Параметр | Обязательный | Тип | Описание |
|---|---|---|---|
proxyType |
да | string | http, socks4 или socks5 |
proxyAddress |
да | string | IP-адрес прокси |
proxyPort |
да | int | Порт прокси |
proxyLogin |
нет | string | Логин для авторизации на прокси |
proxyPassword |
нет | string | Пароль для авторизации на прокси |
Примеры объекта task
// RecaptchaV2TaskProxyless
{
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"isInvisible": false
}
// RecaptchaV2Task (ваш прокси)
{
"type": "RecaptchaV2Task",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080,
"proxyLogin": "user",
"proxyPassword": "password",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."
}
Пример ответа getTaskResult
Пока задача находится в обработке:
{
"errorId": 0,
"status": "processing"
}
После успешного решения:
{
"errorId": 0,
"status": "ready",
"solution": {
"gRecaptchaResponse": "03AGdBq..."
}
}
Значение solution.gRecaptchaResponse необходимо передать в виджет reCAPTCHA или в параметр g-recaptcha-response формы.
reCAPTCHA v3#
Тип RecaptchaV3TaskProxyless. Прокси для v3 не требуется: задачи решаются с IP-адресов сервиса.
| Параметр | Обязательный | Тип | Описание |
|---|---|---|---|
websiteURL |
да | string | Полный URL страницы с капчей |
websiteKey |
да | string | Site key виджета reCAPTCHA v3 |
minScore |
да | float | Минимально допустимый score токена, например 0.3, 0.7 или 0.9. Чем выше значение, тем сложнее и дольше решается задача |
pageAction |
нет | string | Значение параметра action, которое задаёт сайт при вызове grecaptcha.execute(). Если известно — передавайте, это повышает вероятность принятия токена сайтом |
isEnterprise |
нет | bool | true, если на сайте используется reCAPTCHA v3 Enterprise |
apiDomain |
нет | string | Домен, с которого подгружается скрипт reCAPTCHA (www.google.com или www.recaptcha.net), если сайт использует нестандартный домен |
Пример объекта task
// RecaptchaV3TaskProxyless
{
"type": "RecaptchaV3TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"minScore": 0.3,
"pageAction": "login"
}
Пример ответа getTaskResult
Пока задача находится в обработке:
{
"errorId": 0,
"status": "processing"
}
После успешного решения:
{
"errorId": 0,
"status": "ready",
"solution": {
"gRecaptchaResponse": "03AGdBq..."
}
}
Полученный токен (solution.gRecaptchaResponse) используется так же, как и обычный токен reCAPTCHA v3.
Поиск sitekey и callback-функции reCAPTCHA на странице#
Если на странице несколько виджетов reCAPTCHA или callback не виден напрямую в разметке, найти sitekey и функцию обратного вызова можно через объект ___grecaptcha_cfg, в котором Google хранит конфигурацию всех отрендеренных виджетов. Выполните в консоли разработчика (или встройте в скрипт автоматизации) следующий код — он вернёт массив со всеми найденными клиентами reCAPTCHA (и v2, и v3) вместе с их sitekey, pageurl и ссылкой на callback:
function findRecaptchaClients() {
// eslint-disable-next-line camelcase
if (typeof (___grecaptcha_cfg) !== 'undefined') {
// eslint-disable-next-line camelcase, no-undef
return Object.entries(___grecaptcha_cfg.clients).map(([cid, client]) => {
const data = { id: cid, version: cid >= 10000 ? 'V3' : 'V2' };
const objects = Object.entries(client).filter(([_, value]) => value && typeof value === 'object');
objects.forEach(([toplevelKey, toplevel]) => {
const found = Object.entries(toplevel).find(([_, value]) => (
value && typeof value === 'object' && 'sitekey' in value && 'size' in value
));
if (typeof toplevel === 'object' && toplevel instanceof HTMLElement && toplevel['tagName'] === 'DIV'){
data.pageurl = toplevel.baseURI;
}
if (found) {
const [sublevelKey, sublevel] = found;
data.sitekey = sublevel.sitekey;
const callbackKey = data.version === 'V2' ? 'callback' : 'promise-callback';
const callback = sublevel[callbackKey];
if (!callback) {
data.callback = null;
data.function = null;
} else {
data.function = callback;
const keys = [cid, toplevelKey, sublevelKey, callbackKey].map((key) => `['${key}']`).join('');
data.callback = `___grecaptcha_cfg.clients${keys}`;
}
}
});
return data;
});
}
return [];
}
Использование:
let res = findRecaptchaClients()
console.log(res)
Для каждого найденного клиента data.version подскажет, v2 это или v3, data.sitekey — значение для поля websiteKey в запросе createTask, а data.callback — путь к функции обратного вызова, которую нужно выполнить с токеном после получения решения (см. «Как использовать полученный токен» ниже).
Cloudflare Turnstile#
Типы TurnstileTaskProxyless и TurnstileTask.
| Параметр | Обязательный | Тип | Описание |
|---|---|---|---|
websiteURL |
да | string | Полный URL страницы, где размещён виджет Turnstile |
websiteKey |
да | string | Значение data-sitekey виджета Turnstile |
action |
нет | string | Значение атрибута data-action, если задано на сайте |
cData |
нет | string | Значение атрибута data-cdata (custom payload), если сайт его использует |
pageData |
нет | string | Значение параметра chlPageData для более сложных проверок Turnstile |
userAgent |
нет | string | User-Agent, под которым будет решаться и в дальнейшем использоваться токен — токен привязан к User-Agent, поэтому его нужно передавать тем же браузером/ботом, что и решался |
Только для TurnstileTask (решение через ваш прокси), дополнительно:
| Параметр | Обязательный | Тип | Описание |
|---|---|---|---|
proxyType |
да | string | http, socks4 или socks5 |
proxyAddress |
да | string | IP-адрес прокси |
proxyPort |
да | int | Порт прокси |
proxyLogin |
нет | string | Логин для авторизации на прокси |
proxyPassword |
нет | string | Пароль для авторизации на прокси |
Примеры объекта task
// TurnstileTaskProxyless
{
"type": "TurnstileTaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "0x4AAAAAAAxxxxxxxxxxxxxxxx"
}
// TurnstileTask (ваш прокси)
{
"type": "TurnstileTask",
"websiteURL": "https://example.com/login",
"websiteKey": "0x4AAAAAAAxxxxxxxxxxxxxxxx",
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080
}
Пример ответа getTaskResult
Пока задача находится в обработке:
{
"errorId": 0,
"status": "processing"
}
После успешного решения:
{
"errorId": 0,
"status": "ready",
"solution": {
"token": "0.zxcv..."
}
}
Полученный токен (solution.token) необходимо передать в callback-функцию виджета или в поле cf-turnstile-response, в зависимости от способа интеграции Turnstile на сайте.
Сложный случай: Cloudflare Challenge page#
Отдельная и более сложная ситуация — страница Cloudflare Challenge, где помимо websiteKey виджету могут передаваться дополнительные параметры cData, chlPageData и action, без которых токен не будет принят. В этом случае нужно перехватить вызов turnstile.render, чтобы вытащить эти значения, а также перехватить определение callback-функции и передать в запросе userAgent вашего браузера.
Для перехвата параметров встройте следующий JavaScript на страницу до того, как загрузится сам виджет Cloudflare Turnstile:
const i = setInterval(()=>{
if (window.turnstile) {
clearInterval(i)
window.turnstile.render = (a,b) => {
let p = {
type: "TurnstileTaskProxyless",
websiteKey: b.sitekey,
websiteURL: window.location.href,
data: b.cData,
pagedata: b.chlPageData,
action: b.action,
userAgent: navigator.userAgent
}
console.log(JSON.stringify(p))
window.tsCallback = b.callback
return 'foo'
}
}
},10)
Скрипт подменяет turnstile.render собственной функцией: она перехватывает объект конфигурации b (в котором Cloudflare передаёт sitekey, cData, chlPageData, action и callback), логирует готовый объект task для createTask и сохраняет ссылку на исходную callback-функцию в window.tsCallback, чтобы вызвать её позже с токеном.
Альтернативный подход — перехватить сетевой запрос к скрипту api.js и подменить его собственным скриптом, который возвращает нужные параметры и делает callback-функцию доступной глобально (например, через window).
Когда решение получено от getTaskResult, останется выполнить сохранённую callback-функцию, передав токен аргументом:
window.tsCallback('ТОКЕН_ИЗ_SOLUTION');