Как использовать JS и Puppeteer для обхода капчи-слайдера

Друзья, предлагаю вашему вниманию перевод статьи «How to bypass “slider CAPTCHA” with JS and Puppeteer» автора Filip Vitas.

Спам для владельца сайта – огромная проблема. С другой стороны, капчи сводят меня с ума и ухудшают пользовательский опыт.

Капчи отстой. Скажем прямо. Есть много способов прохождения верификации и каждый из них плох.

В последние годы боты умнеют с каждым днем, и защитить от них сайт становится непросто. При достаточном количестве времени и ресурсов можно обойти почти любую капчу. К Puppeteer есть плагины для прохождения Recaptcha. Некоторые компании предоставляют сервисы специально для этого. Например, 2Captcha. Вот как можно использовать Puppeteer и 2Captcha

Есть сайты, где в качестве альтернативы используется капча со слайдером (“сдвиньте ползунок для верификации”). Но зачем кому-то вообще использовать настолько простую капчу с ползунком?

Причины следующие:

  • Большинство ботов работают не на JS, поэтому вы можете их остановить
  • Слайдер более «дружелюбен» к пользователю
  • Для пользователей мобильных устройств «свайпнуть» слайдер – привычное действие

Так что для людей слайдеры понятны и просты.Давайте попробуем обойти кое-какие капчи со слайдером.

Передвиньте ползунок для отправки

jQuery используется в веб-формах, где есть элемент “передвиньте ползунок для отправки”. Это альтернатива капче, предотвращающая спам при заполнении веб-форм.

Сперва мы заполняем поля ввода. Чтобы передвинуть этот слайдер, нам нужно:

  • навести курсор на центр ползунка
  • нажать кнопку мыши
  • передвинуть мышь
  • отпустить кнопку мыши
const puppeteer = require(‘puppeteer’);

async function run() {
const browser = await puppeteer.launch({
defaultViewport: { width: 1366, height: 768 },
headless: false,
});

const page = await browser.newPage();

await page.goto(‘http://kthornbloom.com/slidetosubmit/’);

await page.type(‘input[name=”name”]’, ‘Puppeteer Bot’);

await page.type(‘input[name=”email”]’, ‘[email protected]‘);

let sliderElement = await page.$(‘.slide-submit’);
let slider = await sliderElement.boundingBox();

let sliderHandle = await page.$(‘.slide-submit-thumb’);
let handle = await sliderHandle.boundingBox();

await page.mouse.move(handle.x + handle.width / 2, handle.y + handle.height / 2);
await page.mouse.down();

await page.mouse.move(handle.x + slider.width, handle.y + handle.height / 2, { steps: 10 });
await page.mouse.up();

// success!

await browser.close();
}

run();

Готово. Это было просто.

Слайдер регистрации Dipbit

Dipbit – сайт для обмена цифровых валют. Обе страницы – и ввод логина, и регистрация – содержат элемент “передвиньте ползунок для верификации”.

Dipbit пытается быть немного умным, поэтому нам нужно добавить код для сокрытия работы Puppeteer.

const puppeteer = require(‘puppeteer’);

async function run() {
const browser = await puppeteer.launch({
defaultViewport: { width: 1366, height: 768 },
headless: false,
});

const page = await browser.newPage();

await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, ‘webdriver’, {
get: () => false,
});
});

await page.goto(‘https://www.example.com/’);

await page.type(‘input[name=”login”]’, ‘your_login’);
await page.type(‘input[name=”password”]’, ‘your_password’);

await page.click(‘input[name=”submit”]’);

await page.waitForNavigation();

// …

await browser.close();
}

run();

Taobao

Taobao – китайский сайт онлайн-покупок, принадлежащий Alibaba. Их слайдер регистрации похож на аналогичный у Dipbit. Единственное отличие – регистрационная форма находится внутри iframe. Но для Puppeteer это не проблема.

const puppeteer = require(‘puppeteer’);

async function run() {
const browser = await puppeteer.launch({
headless: false,
defaultViewport: { width: 1366, height: 768 },
});

const page = await browser.newPage();

await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, ‘webdriver’, {
get: () => false,
});
});

await page.goto(‘https://world.taobao.com/markets/all/sea/register’);

let frame = page.frames()[1];

await frame.waitForSelector(‘.nc_iconfont.btn_slide’);

const sliderElement = await frame.$(‘.slidetounlock’);
const slider = await sliderElement.boundingBox();

const sliderHandle = await frame.$(‘.nc_iconfont.btn_slide’);
const handle = await sliderHandle.boundingBox();

await page.mouse.move(handle.x + handle.width / 2, handle.y + handle.height / 2);
await page.mouse.down();

await page.mouse.move(handle.x + slider.width, handle.y + handle.height / 2, { steps: 50 });
await page.mouse.up();

// success!

await browser.close();
}

run();

Капча-слайдер с головоломкой

Я наткнулся на компонент “передвиньте полузнок…” фреймворка Vue, который должен быть простым для людей и сложным для ботов.

Этот способ верификации выводит изображение, создает два canvas-слоя и один слайдер. Он обрабатывает исходное изображение как части паззла. Пользователю нужно двигать слайдер так, чтобы части подошли. Как только части подошли, пользователь отпускает слайдер, и верификация пройдена.

Эта капча «рандомизирует» положения частей паззла, чтобы запутать ботов.

Я не собирался делать здесь что-то особенное, вроде ML или OCR, поэтому просто буду понемногу двигать слайдер, сравнивая конечное и исходное изображения.

Для сравнения изображений я использую rembrandt.js library. Как только найдется минимально отличающееся, я передвину слайдер в наилучшее положение и отпущу кнопку мыши.

Если вы проглядели кое-что крутое – я рандомизирую движение слайдера по оси Y, чтобы имитировать движения мыши реального пользователя.

await page.mouse.move(
handle.x + currentPosition,
handle.y + handle.height / 2 + Math.random() * 10 – 5
);

Все примеры кода доступны здесь: github repo, копируйте на здоровье всё, что захотите.

Заключение

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

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

Несмотря на всё это, информация предоставлена исключительно в образовательных целях, используйте Puppeteer осмотрительно.

 

Источник

Читайте также