Как обойти слайдер-капчу
Демо-репозиторий с примерами: github.com/2captcha/custom-slider-demo
Приведённый в статье код является примером. Каждая реализация слайдер-капчи уникальна: сайты используют разные структуры, проверки и поведенческие анализаторы. Полная адаптация под вашу задачу лежит на вашей стороне.
Введение
Слайдер-капчи широко используются на веб-сайтах для предотвращения доступа ботов к ограниченному контенту или выполнения несанкционированных действий. Хотя они обеспечивают простой и удобный способ проверки пользователей, они могут ограничивать доступность, вызывать раздражение у пользователей и создавать сложности при тестировании приложений и сайтов.
Для обычных пользователей это удобно: достаточно одного плавного движения мышью или пальцем. Для разработчиков, тестирующих свои приложения или автоматизирующих легальные рабочие процессы, это становится техническим вызовом.
Ключевой момент: Современные капчи анализируют не только конечную позицию ползунка, но и поведенческие паттерны: дрожание мыши, паузы, нелинейность траектории, время реакции.
Преимущества и недостатки
Преимущества
- Простая реализация: Легко интегрируется с минимальными техническими знаниями.
- Доступность: Требуется минимальное взаимодействие с мышью или сенсорным экраном.
- Совместимость с мобильными устройствами: Предусмотрены естественные действия свайпа для пользователей мобильных устройств.
Недостатки
- Проблемы с доступностью: Могут исключать пользователей с ограниченными возможностями.
- Уязвимость к автоматизации: Подвержены обходу с использованием продвинутых методов автоматизации.
- Раздражение пользователей: Может ухудшать пользовательский опыт при неправильной реализации.
Как работает слайдер-капча
Понимание внутренней логики защиты — первый шаг к её обходу. Процесс проверки делится на четыре этапа:
- Генерация задания
Сервер создаёт уникальное изображение с «вырезом» и отдельный фрагмент-пазл. Каждое задание привязано к ID сессии и времени жизни (обычно 30–120 секунд). - Сбор телеметрии
При взаимодействии с ползунком JavaScript записывает:- Координаты курсора (
clientX,clientY) - Временные метки каждого события
mousemove - Скорость, ускорение, микродвижения, паузы
- Факты выхода за пределы трека
- Координаты курсора (
- Серверный анализ
Данные проходят две проверки:- Визуальная: совпадает ли конечная позиция с ожидаемым смещением?
- Поведенческая: соответствует ли траектория человеческому паттерну?
- Выдача токена
При успехе сервер возвращает криптографический токен или куки, который подтверждает прохождение проверки и передаётся в последующих запросах.
Решение
Чтобы обойти слайдер, нужно рассчитать траекторию перемещения ползунка. В большинстве случаев достаточно двух точек:
- Начальная точка — обычно статична (левый край трека), определяется один раз.
- Конечная точка — координаты центра целевого фрагмента пазла.
Вторую точку могут определить работники нашего сервиса: вы отправляете изображение капчи с инструкцией, они указывают нужную координату, API возвращает результат. Для этого используется метод Coordinates в документации.
Подход
Для стабильного обхода необходимо реализовать три независимых, но связанных механизма:
1. Визуальное решение
Определение точных координат, куда нужно переместить ползунок. Вручную писать алгоритмы компьютерного зрения неэффективно для продакшена. Оптимальный путь — делегировать распознавание нашего сервису.
2. Имитация человеческого поведения
Получив координаты, курсор нужно переместить по реалистичной траектории. Человек не двигает мышь по прямой. Его рука совершает:
- Плавное ускорение в начале движения
- Небольшие колебания по вертикали (естественный тремор)
- Корректировки пути в середине
- Замедление перед достижением цели
- Микро-паузы и случайные задержки между событиями
mousemove
Эти параметры реализуются через математические функции сглаживания (easing), синусоидальный шум и рандомизированные тайминги.
3. Маскировка автоматизации
Браузеры для автоматизации оставляют следы: флаг navigator.webdriver, специфичные заголовки, отсутствие плагинов. Современные системы защиты сканируют эти признаки. Маскировка включает:
- Подмену свойств
navigator - Использование аргументов запуска браузера
- Имитацию реального
User-Agent - Добавление задержек между этапами загрузки страницы
Подготовка
Установка зависимостей (Node.js)
bash
# Инициализация проекта
npm init -y
# Установка пакетов
npm install puppeteer @2captcha/captcha-solver dotenv
# Включение поддержки ES6-модулей
npm pkg set type="module"
Установка зависимостей (Python)
bash
pip install playwright requests
playwright install chromium
Настройка API-ключа
Создайте файл .env в корне проекта:
env
APIKEY=ваш_ключ_от_rucaptcha
Загрузка ключа в коде:
javascript
// JavaScript
import { config } from 'dotenv';
config();
const solver = new Solver(process.env.APIKEY);
python
# Python
import os
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("APIKEY")
Концептуальный алгоритм
Вместо копирования кода разберём логику работы, которую вы будете реализовывать под свой проект:
- Инициализация окружения. Запускаем браузер в режиме, близком к пользовательскому. Отключаем детектирование автоматизации, устанавливаем реалистичные параметры окна.
- Навигация и ожидание. Переходим на целевую страницу. Ждём полной загрузки DOM и появления элемента капчи. Обрабатываем всплывающие баннеры согласия.
- Извлечение изображения. Делаем скриншот области капчи или извлекаем
canvas/imgв формате base64. Убеждаемся, что изображение читаемо. - Отправка на решение. Передаём base64-строку в API солвера с чёткой текстовой инструкцией. Ожидаем ответа с координатами
XиY. - Расчёт траектории. Определяем стартовую позицию ползунка. Рассчитываем конечную точку:
start_x + offset_x. Генерируем массив промежуточных координат с функцией сглаживания и шумом. - Имитация перетаскивания. Перемещаем курсор к стартовой точке, делаем паузу, вызываем
mouse.down(), отправляем событияmoveпо траектории с рандомизированными задержками, вызываемmouse.up().
Пример кода
Минимальный пример на Python (Playwright)
python
import asyncio
import math
import random
import requests
from playwright.async_api import async_playwright
API_KEY = "ваш_ключ"
def get_eased_trajectory(start_x, start_y, end_x, end_y, steps=120):
"""Генерирует точки с плавным движением и шумом."""
points = []
for i in range(steps + 1):
t = i / steps
ease = 2 * t * t if t < 0.5 else -1 + (4 - 2 * t) * t
noise_x = math.sin(t * math.pi * 6) * random.uniform(-2.5, 2.5)
noise_y = math.cos(t * math.pi * 4) * random.uniform(-1.0, 1.0)
x = start_x + (end_x - start_x) * ease + noise_x
y = start_y + (end_y - start_y) * ease + noise_y
delay = random.uniform(8, 18) if 0.1 < t < 0.9 else random.uniform(25, 45)
points.append((x, y, delay))
return points
async def solve_slider(url, canvas_selector, slider_selector):
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=True,
args=["--disable-blink-features=AutomationControlled"]
)
page = await browser.new_page()
# Маскировка автоматизации
await page.add_init_script("""
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
Object.defineProperty(navigator, 'languages', { get: () => ['ru-RU','en-US'] });
""")
await page.goto(url, wait_until="networkidle", timeout=30000)
await page.wait_for_selector(canvas_selector, timeout=10000)
# Извлечение изображения капчи
captcha_b64 = await page.evaluate(f"""
() => document.querySelector('{canvas_selector}').toDataURL('image/png').split(',')[1]
""")
# Отправка на решение
resp = requests.post("https://api.rucaptcha.com/createTask", json={
"clientKey": API_KEY,
"task": {
"type": "CoordinatesTask",
"body": captcha_b64,
"comment": "Find puzzle center | Найди центр пазла"
}
}).json()
task_id = resp.get("taskId")
# Ожидание результата
while True:
await asyncio.sleep(3)
res = requests.get("https://api.rucaptcha.com/getTaskResult",
json={"clientKey": API_KEY, "taskId": task_id}).json()
if res.get("status") == "ready":
offset_x = res["solution"]["x"]
break
# Имитация перетаскивания
slider = await page.query_selector(slider_selector)
box = await slider.bounding_box()
start = (box["x"] + box["width"]/2, box["y"] + box["height"]/2)
end = (start[0] + offset_x - random.randint(2, 5), start[1] + random.uniform(-0.5, 0.5))
await page.mouse.move(*start)
await asyncio.sleep(random.uniform(0.4, 0.8))
await page.mouse.down()
for x, y, delay in get_eased_trajectory(*start, *end):
await page.mouse.move(x, y)
await asyncio.sleep(delay / 1000)
await page.mouse.up()
await page.wait_for_selector(".success, .verified", timeout=8000)
print("✅ Капча пройдена")
await browser.close()
📌 Примечание: Это ядро алгоритма. В реальном проекте потребуется обработка
iframe, retry-логика, логирование и адаптация селекторов.
Запуск демонстрационного кода
Также можете просто клонировать репозиторий, установить зависимости и запустить:
bash
# Клонирование репозитория
git clone https://github.com/2captcha/custom-slider-demo.git
cd custom-slider-demo
# Установка зависимостей
npm install # или yarn install
# Настройка API-ключа
echo "APIKEY=ваш_ключ" > .env
# Запуск
npm start
Как адаптировать шаблон под ваш проект
- Подбор селекторов. Откройте DevTools (F12) → найдите элемент изображения капчи и ползунка → скопируйте уникальные CSS-селекторы. Замените
canvasи.slider-buttonв примере. - Работа с iframe. Если капча загружается во фрейме:
python
# Playwright Python frame = page.frame_locator("iframe[src*='captcha']") await frame.locator("canvas").wait_for()javascript// Puppeteer JS const frame = page.frames().find(f => f.url().includes('captcha')); if (frame) await frame.waitForSelector('canvas'); - Настройка инструкций. Чем точнее ваши инструкции в запросе к API, тем выше шанс корректного решения:
"Click exact center of puzzle piece | Точный центр фрагмента пазла" - Тонкая настройка траектории. Если сайт отклоняет решение: увеличьте
stepsдо 150–200, усильте амплитуду шума, добавьте случайные микро-паузы внутри цикла. - Отладка в видимом режиме. Замените
headless=Trueнаheadless=False, чтобы наблюдать за движением курсора в реальном времени.
Отвечаем на вопросы
Зачем использовать Puppeteer / Playwright?
Эти фреймворки предоставляют низкоуровневый доступ к событиям браузера: mousemove, mousedown, mouseup. Это позволяет точно имитировать действия пользователя, что критично для обхода поведенческих проверок.
Почему капча не решается с первого раза?
| Проблема | Решение |
|---|---|
| Неточные координаты | Уточните textinstructions, добавьте визуальную инструкцию |
| Детект автоматизации | Усильте маскировку navigator, добавьте аргументы запуска |
| Неверные селекторы | Проверьте актуальность вёрстки через DevTools |
| Капча в iframe | Используйте frame_locator или page.frames() |
Как отладить скрипт?
Установите headless: false в настройках браузера — так вы увидите действия в реальном времени. Добавьте логирование:
javascript
page.on('console', msg => console.log('Browser:', msg.text()));
page.on('pageerror', err => console.error('Error:', err.message));
Полезные материалы
- Документация ruCaptcha API — методы, параметры, коды ошибок
- Демо-репозиторий — готовые примеры для разных типов капч
Подводя итог: обход слайдер-капчи строится на понятной цепочке действий. Вы забираете картинку, отправляете её на распознавание, плавно ведёте ползунок и проверяете ответ сервера. Код из статьи задаёт только базовую структуру. Вам останется подставить свои селекторы, выверить паузы между движениями и дописать обработку ошибок под ваш проект. Когда точное попадание сочетается с живым поведением курсора, скрипт работает стабильно и без сбоев.