Друзья, предлагаю вашему вниманию перевод статьи «How to bypass “slider CAPTCHA” with JS and Puppeteer» автора Filip Vitas.
Спам для владельца сайта – огромная проблема. С другой стороны, капчи сводят меня с ума и ухудшают пользовательский опыт.
Капчи отстой. Скажем прямо. Есть много способов прохождения верификации и каждый из них плох.
В последние годы боты умнеют с каждым днем, и защитить от них сайт становится непросто. При достаточном количестве времени и ресурсов можно обойти почти любую капчу. К Puppeteer есть плагины для прохождения Recaptcha. Некоторые компании предоставляют сервисы специально для этого. Например, 2Captcha. Вот как можно использовать Puppeteer и 2Captcha
Есть сайты, где в качестве альтернативы используется капча со слайдером (“сдвиньте ползунок для верификации”). Но зачем кому-то вообще использовать настолько простую капчу с ползунком?
Причины следующие:
- Большинство ботов работают не на JS, поэтому вы можете их остановить
- Слайдер более «дружелюбен» к пользователю
- Для пользователей мобильных устройств «свайпнуть» слайдер – привычное действие
Так что для людей слайдеры понятны и просты.Давайте попробуем обойти кое-какие капчи со слайдером.
Передвиньте ползунок для отправки
jQuery используется в веб-формах, где есть элемент “передвиньте ползунок для отправки”. Это альтернатива капче, предотвращающая спам при заполнении веб-форм.
Сперва мы заполняем поля ввода. Чтобы передвинуть этот слайдер, нам нужно:
- навести курсор на центр ползунка
- нажать кнопку мыши
- передвинуть мышь
- отпустить кнопку мыши
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 пытается быть немного умным, поэтому нам нужно добавить код для сокрытия работы Puppeteer. async function run() { const page = await browser.newPage(); await page.evaluateOnNewDocument(() => { await page.goto(‘https://www.example.com/’); await page.type(‘input[name=”login”]’, ‘your_login’); await page.click(‘input[name=”submit”]’); await page.waitForNavigation(); // … await browser.close(); run();
Taobao – китайский сайт онлайн-покупок, принадлежащий Alibaba. Их слайдер регистрации похож на аналогичный у Dipbit. Единственное отличие – регистрационная форма находится внутри iframe. Но для Puppeteer это не проблема. async function run() { const page = await browser.newPage(); await page.evaluateOnNewDocument(() => { 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 sliderHandle = await frame.$(‘.nc_iconfont.btn_slide’); await page.mouse.move(handle.x + handle.width / 2, handle.y + handle.height / 2); await page.mouse.move(handle.x + slider.width, handle.y + handle.height / 2, { steps: 50 }); // success! await browser.close(); run();
Я наткнулся на компонент “передвиньте полузнок…” фреймворка Vue, который должен быть простым для людей и сложным для ботов. Этот способ верификации выводит изображение, создает два canvas-слоя и один слайдер. Он обрабатывает исходное изображение как части паззла. Пользователю нужно двигать слайдер так, чтобы части подошли. Как только части подошли, пользователь отпускает слайдер, и верификация пройдена. Эта капча «рандомизирует» положения частей паззла, чтобы запутать ботов. Я не собирался делать здесь что-то особенное, вроде ML или OCR, поэтому просто буду понемногу двигать слайдер, сравнивая конечное и исходное изображения. Для сравнения изображений я использую rembrandt.js library. Как только найдется минимально отличающееся, я передвину слайдер в наилучшее положение и отпущу кнопку мыши. Если вы проглядели кое-что крутое – я рандомизирую движение слайдера по оси Y, чтобы имитировать движения мыши реального пользователя. Все примеры кода доступны здесь: github repo, копируйте на здоровье всё, что захотите. Это всегда дилемма: нужно ли сайтам быть более дружелюбными и использовать простые для прохождения капчи, или они должны агрессивно защищать себя от ботов, жертвуя удобством пользования. Война между сайтами и ботами не заканчивается никогда. Какой бы метод верификации ни использовался, это лишь вопрос времени, прежде чем кто-то придумает, как его обойти. Несмотря на всё это, информация предоставлена исключительно в образовательных целях, используйте Puppeteer осмотрительно.Слайдер регистрации Dipbit
const browser = await puppeteer.launch({
defaultViewport: { width: 1366, height: 768 },
headless: false,
});
Object.defineProperty(navigator, ‘webdriver’, {
get: () => false,
});
});
await page.type(‘input[name=”password”]’, ‘your_password’);
}Taobao
const browser = await puppeteer.launch({
headless: false,
defaultViewport: { width: 1366, height: 768 },
});
Object.defineProperty(navigator, ‘webdriver’, {
get: () => false,
});
});
const slider = await sliderElement.boundingBox();
const handle = await sliderHandle.boundingBox();
await page.mouse.down();
await page.mouse.up();
}Капча-слайдер с головоломкой
handle.x + currentPosition,
handle.y + handle.height / 2 + Math.random() * 10 – 5
);
Заключение