API Tutorials

Объяснение параметра reCAPTCHA Data-S

Решатель возвращает недействительный токен, хотя sitekey и pageurl указаны верно? Почти всегда причина одна — на странице есть атрибут data-s, и его забыли передать в запрос. Это сессионный токен, который встречается в отдельных реализациях reCAPTCHA, в первую очередь на сервисах Google — в поиске, YouTube, Google Play. Если он есть в разметке, без него решение не пройдёт проверку.

Коротко:

  • data-s — не баг и не лишнее поле, а обязательный параметр в узком круге сценариев
  • встречается почти исключительно на доменах самого Google
  • если атрибут есть в HTML, а его не передали — решение не пройдёт, часто без внятной ошибки

Что такое data-s и как он выглядит

data-s — это токен сеанса, который генерирует сервер и встраивает в HTML виджета reCAPTCHA. Он привязывает конкретный запрос CAPTCHA к серверной сессии и не даёт использовать один и тот же токен в разных сессиях.

Где искать атрибут в HTML

<!-- reCAPTCHA widget with data-s parameter -->
<div class="g-recaptcha"
     data-sitekey="6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp"
     data-s="AB2grfE8_kyMp3XYRuJo5c..."
     data-callback="onCaptchaSolved">
</div>

Атрибут data-s стоит рядом со стандартным data-sitekey внутри <div> виджета reCAPTCHA.

Ключевые характеристики параметра

  • Формат — строка в Base64, 200–500 символов
  • Время жизни — одноразовый, привязан к текущей загрузке страницы
  • Область действия — завязан на конкретный сеанс, нельзя переиспользовать между загрузками
  • Обязательность — да, если атрибут присутствует в HTML: без него решение не пройдёт
  • Обновление — новое значение при каждой загрузке или обновлении страницы

Как data-s работает изнутри

User triggers CAPTCHA (e.g., Google flags unusual search traffic)
    ↓
Google serves a CAPTCHA page with:

  - data-sitekey (site key, same for all Google search CAPTCHAs)
  - data-s (session token, unique per page load)
    ↓
reCAPTCHA widget initializes with both parameters
    ↓
Challenge completion generates a g-recaptcha-response token
    ↓
Token is submitted alongside the session reference
    ↓
Google validates token + session binding
    ↓
If data-s was not used during solving: "invalid-input-response" or silent failure

По сути data-s работает как nonce — одноразовое значение, которое привязывает CAPTCHA-задачу к конкретной серверной сессии. Решатель обязан использовать именно это значение при генерации токена, иначе итоговый токен не совпадёт с ожидаемой сессией.

Когда data-s действительно нужен

data-s встречается НЕ в большинстве реализаций reCAPTCHA — это скорее исключение. Основные места:

  • Google Поиск, страница /sorry/ при подозрительном трафике — всегда, обязателен для решения этой CAPTCHA
  • YouTube — иногда, в отдельных сценариях проверки
  • Google Play — иногда, при проверке карточек приложений
  • Google Forms — редко, в ограниченном числе форм
  • Сторонние сайты с reCAPTCHA — почти никогда, обычные интеграции data-s не используют

Если вы не работаете с сервисами самого Google, скорее всего data-s вам не встретится вообще. А если решатель раз за разом возвращает невалидный токен именно для CAPTCHA в поиске Google — в 9 случаях из 10 дело именно в пропущенном data-s.

Для команд, парсящих Google Поиск с серверов в европейских дата-центрах или через общие облачные IP (частый случай для разработчиков из России, Беларуси, Казахстана и Украины), страница «необычный трафик» встречается заметно чаще — это репутация IP, а не баг кода. Если заодно собираете данные со страницы, держите в голове требования 152-ФЗ «О персональных данных» или GDPR для кросс-граничных случаев.

Частые ошибки с data-s

Большинство «случайных» сбоев решения сводится к паре типовых грабель:

  • Пропустили data-s, хотя он есть в разметке — токен не проходит проверку, часто без явной ошибки. Перед отправкой всегда проверяйте атрибут на виджете.
  • Добавили data-s туда, где его нет — ошибка решения или отклонённый запрос. Передавайте параметр только если он реально есть в HTML.
  • Используете один и тот же data-s для нескольких загрузок — невалидный токен. Извлекайте свежее значение при каждой загрузке страницы.
  • Кодируете data-s в URL вручную — параметр приходит в испорченном виде. Передавайте «сырое» значение Base64 без дополнительного кодирования.
  • Берёте data-s со страницы, открытой несколько минут назад — токен не совпадает с текущей сессией. Извлекайте значение прямо перед отправкой запроса решателю.

Как извлечь data-s со страницы

Извлечение через Python

import requests
from bs4 import BeautifulSoup
import re

def extract_recaptcha_params(url):
    """Extract reCAPTCHA parameters including data-s from a page."""
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/120.0.0.0 Safari/537.36",
    }

    response = requests.get(url, headers=headers, timeout=15)
    soup = BeautifulSoup(response.text, "html.parser")

    # Find reCAPTCHA widget div
    widget = soup.find("div", class_="g-recaptcha")
    if not widget:
        # Try finding by data-sitekey attribute
        widget = soup.find(attrs={"data-sitekey": True})

    if not widget:
        return {"error": "No reCAPTCHA widget found"}

    params = {
        "sitekey": widget.get("data-sitekey"),
        "data_s": widget.get("data-s"),
        "callback": widget.get("data-callback"),
        "size": widget.get("data-size"),
        "has_data_s": widget.get("data-s") is not None,
    }

    return params

# Example: Google "unusual traffic" page
params = extract_recaptcha_params("https://www.google.com/sorry/index")
print(params)
# {
#   "sitekey": "6LfwuyUT...",
#   "data_s": "AB2grfE8_kyMp3...",
#   "has_data_s": True
# }

Извлечение через Node.js

const axios = require("axios");
const cheerio = require("cheerio");

async function extractRecaptchaParams(url) {
    const { data: html } = await axios.get(url, {
        headers: {
            "User-Agent":
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
                "AppleWebKit/537.36 (KHTML, like Gecko) " +
                "Chrome/120.0.0.0 Safari/537.36",
        },
        timeout: 15000,
    });

    const $ = cheerio.load(html);
    const widget = $(".g-recaptcha, [data-sitekey]").first();

    if (widget.length === 0) {
        return { error: "No reCAPTCHA widget found" };
    }

    return {
        sitekey: widget.attr("data-sitekey"),
        dataS: widget.attr("data-s") || null,
        callback: widget.attr("data-callback") || null,
        hasDataS: !!widget.attr("data-s"),
    };
}

extractRecaptchaParams("https://www.google.com/sorry/index")
    .then(console.log);

Извлечение через Selenium (для динамических страниц)

from selenium import webdriver
from selenium.webdriver.common.by import By

def extract_data_s_selenium(driver, url):
    """Extract data-s from a dynamically loaded reCAPTCHA page."""
    driver.get(url)

    # Wait for reCAPTCHA widget to load
    import time
    time.sleep(3)

    try:
        widget = driver.find_element(By.CSS_SELECTOR, ".g-recaptcha, [data-sitekey]")
        return {
            "sitekey": widget.get_attribute("data-sitekey"),
            "data_s": widget.get_attribute("data-s"),
        }
    except Exception:
        return {"error": "Widget not found"}

Быстрая проверка без единой строчки кода: откройте DevTools → Elements, найдите <div class="g-recaptcha"> (или элемент с data-sitekey) и посмотрите, есть ли рядом data-s. Ещё быстрее — выполнить в консоли document.querySelector('[data-sitekey]')?.getAttribute('data-s'): null означает, что атрибута нет.

Как передать data-s в API CaptchaAI

Если data-s присутствует в разметке, включите его в запрос к CaptchaAI:

Python

import requests
import time

API_KEY = "YOUR_API_KEY"

# Step 1: Extract parameters from the CAPTCHA page
sitekey = "6LfwuyUTAAAAAOAmoS0fdqijC2PbbdH4kjq62Y1b"
data_s = "AB2grfE8_kyMp3XYRuJo5c..."  # Extracted from data-s attribute
page_url = "https://www.google.com/sorry/index?continue=..."

# Step 2: Submit to CaptchaAI WITH data-s
submit = requests.post("https://ocr.captchaai.com/in.php", data={
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": sitekey,
    "pageurl": page_url,
    "data-s": data_s,  # Include data-s parameter
    "json": 1,
})

task_id = submit.json()["request"]

# Step 3: Poll for result
for _ in range(60):
    time.sleep(5)
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY,
        "action": "get",
        "id": task_id,
        "json": 1,
    }).json()

    if result.get("status") == 1:
        token = result["request"]
        print(f"Token: {token[:60]}...")
        # Submit this token to the Google CAPTCHA form
        break

Node.js

const axios = require("axios");

async function solveWithDataS(sitekey, dataS, pageUrl) {
    const API_KEY = "YOUR_API_KEY";

    // Submit with data-s
    const { data: submit } = await axios.post(
        "https://ocr.captchaai.com/in.php",
        new URLSearchParams({
            key: API_KEY,
            method: "userrecaptcha",
            googlekey: sitekey,
            pageurl: pageUrl,
            "data-s": dataS,
            json: 1,
        })
    );

    const taskId = submit.request;

    // Poll
    for (let i = 0; i < 60; i++) {
        await new Promise((r) => setTimeout(r, 5000));
        const { data: result } = await axios.get(
            "https://ocr.captchaai.com/res.php",
            {
                params: {
                    key: API_KEY,
                    action: "get",
                    id: taskId,
                    json: 1,
                },
            }
        );

        if (result.status === 1) {
            return result.request;
        }
    }

    throw new Error("Timeout");
}

Готовая утилита для извлечения data-s

Один класс, который сам решает, нужно ли включать data-s в запрос — не придётся дублировать проверку в каждом скрипте:

import requests
from bs4 import BeautifulSoup

class RecaptchaExtractor:
    """Extract reCAPTCHA parameters from any page."""

    def __init__(self, url, session=None):
        self.url = url
        self.session = session or requests.Session()
        self.params = None

    def extract(self):
        """Extract sitekey, data-s, and other parameters."""
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                          "AppleWebKit/537.36 (KHTML, like Gecko) "
                          "Chrome/120.0.0.0 Safari/537.36",
        }

        response = self.session.get(self.url, headers=headers, timeout=15)
        soup = BeautifulSoup(response.text, "html.parser")

        widget = soup.find(attrs={"data-sitekey": True})
        if not widget:
            raise ValueError("No reCAPTCHA widget found on page")

        self.params = {
            "sitekey": widget["data-sitekey"],
            "pageurl": self.url,
        }

        # Include data-s only if present
        data_s = widget.get("data-s")
        if data_s:
            self.params["data-s"] = data_s

        return self.params

    def build_solver_payload(self, api_key):
        """Build CaptchaAI submission payload with correct parameters."""
        if not self.params:
            self.extract()

        payload = {
            "key": api_key,
            "method": "userrecaptcha",
            "googlekey": self.params["sitekey"],
            "pageurl": self.params["pageurl"],
            "json": 1,
        }

        # Only include data-s when it exists
        if "data-s" in self.params:
            payload["data-s"] = self.params["data-s"]

        return payload


# Usage
extractor = RecaptchaExtractor("https://www.google.com/sorry/index?continue=...")
payload = extractor.build_solver_payload("YOUR_API_KEY")
# payload includes data-s only when present on the page

Часто задаваемые вопросы

Всегда ли нужен data-s для решения reCAPTCHA?

Нет. Атрибут встречается только в узком подмножестве реализаций reCAPTCHA, в первую очередь на сервисах самого Google. На обычных сторонних сайтах достаточно sitekey и pageurl. Проверяйте наличие data-s на виджете перед каждой отправкой.

Почему CAPTCHA в Google Поиске не решается, хотя sitekey верный?

Самая частая причина — пропущенный data-s. Такие CAPTCHA всегда включают этот параметр, и без него решение не пройдёт. Извлеките data-s из <div> виджета reCAPTCHA и передайте вместе с остальными полями.

Нужен ли data-s при работе с reCAPTCHA v3?

Обычно нет: v3 чаще всего работает в фоне и не рендерит классический виджет с data-sitekey/data-s тем же способом, что v2. Если атрибут всё же присутствует на конкретной странице, передавайте его так же, как описано выше.

А если сайт использует reCAPTCHA Enterprise?

Разметка виджета может отличаться, а нужные значения иногда лежат не в data-атрибутах <div>, а в объекте инициализации JS. Принцип тот же: найдите на странице значение, аналогичное data-s, и передайте его тем же полем в запросе к CaptchaAI.

Что делать, если data-s не находится ни в HTML, ни в консоли браузера?

Проверьте, не подгружается ли виджет внутри стороннего iframe — тогда data-s не попадёт в DOM родительской страницы. Откройте вкладку Network и найдите запрос к google.com/recaptcha/...: значение обычно видно там даже без доступа к разметке iframe.

Итог

data-s — токен привязки к сессии, который встречается в отдельных реализациях reCAPTCHA, в первую очередь на сервисах Google. Если он есть в разметке, извлеките его из HTML виджета и передайте в запрос к CaptchaAI вместе с sitekey и pageurl. Проверяйте наличие data-s перед каждой отправкой: включайте — если он есть, пропускайте — если его нет. Для CAPTCHA в Google Поиске этот параметр обязателен всегда.

Похожие статьи

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