Решение Амазон капчи Waf Captcha на полном автомате, имея за плечами практически нулевой опыт в разработке

от автора

Небольшой эпиграф — если вы делаете инструкцию, так делайте ее до конца, а то в инструкции как решить Амазон капчу — джун ногу сломит.

Собственно к чему все это? Да к тому, что когда мне потребовалось решить капчу от Амазон, пресловутую Waf Captcha я пошел копать на сервис, которым постоянно пользуюсь при работе с Кей Коллектором, и некоторыми другими сервисами (2капча — жаль Хабр банит статьи за реферальные ссылки).

Ну и нашел там инструкцию, ссылку на которую собственно и привел выше. Как вам вероятно стало понятно из эпиграфа — я ни черта не понял, вернее я понял, что надо использовать АПИ, но на этом все…

С Селениумом было реально проще.

Главная проблема — малый таймаут, который выделяется на решение со стороны Амазона. Время на решение капчи ограничено и если ответа нет, то капча обновляется (у нее обновляются 2 параметра — iv и context).

Получается, что таймаут свежести капчи около 30 секунд, а за это время необходимо найти на странице параметры, скопировать их, вставить в код скрипта и запустить его, после этого 2капча должна ее решить и вернуть правильный ответ. Я пробовал это сделать пару безуспешных часа, вырабатывал автоматизм действий, но увы, на поиск и замену изменяемых параметров уходит не менее 12-15 секунд, и остается от 15 до 18 секунд мы решение капчи сервисом, что в нынешних реалиях звучит достаточно фантастически.

Тут нужен другой подход, искать и подставлять параметры должен скрипт, но как его написать человеку, который в своей жизни ничего сложнее Ahrefs не видел?

Вот именно по этой причине, я считаю, что инструкции, подобные упомянутым в статье необходимо делать более подробными, чем — «Просто используй Апи, ты че совсем куку?»

Решение

По итогу решение было найдено и заняло оно у меня примерно 3 часа времени. Рассказываю, как же джуну решить Амазон капчу на полном автомате.

Нам понадобится GPT Chat и в моем случае видео распознавания Амазон капчи (вам оно не понадобится, так как я дам вам уже готовый собранный файл).

Видео я взял у знакомого проггера, но он запретил его выкладывать в паблик, так как оно не обезличено.

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

Итак, поехали по порядку:

Я взял видео, сделал 3 скриншота и загрузил их в GPT Chat и попросил его переписать мне этот код текстом.

В видео было несколько файлов, но показано только содержимое 2 из них — index.js и inject.js — с них я и начал.

Не буду утомлять вас расшифровкой скринов (там пришлось немного повозиться и собрать код со скриншотов в единое целое но по итогу я получил два вот таких куска кода для двух файлов:

// index.js import { launch } from 'puppeteer' import { Captcha } from '2captcha-ts' import { readFileSync } from 'fs'  const solver = new Captcha(process.env.APIKEY)  const target = 'УРЛ сайта где встречается капча'  const example = async () => {   const browser = await launch({     headless: false,     devtools: true   })    const [page] = await browser.pages()    const preloadFile = readFileSync('./inject.js', 'utf8')   await page.evaluateOnNewDocument(preloadFile)    // Here we intercept the console messages to catch the message logged by inject.js script   page.on('console', async (msg) => {     const txt = msg.text()     if (txt.includes('intercepted-params:')) {       const params = JSON.parse(txt.replace('intercepted-params:', ''))        const wafParams = {         pageurl: target,         sitekey: params.key,         iv: params.iv,         context: params.context,         challenge_script: params.challenge_script,         captcha_script: params.captcha_script       }       console.log(wafParams)        try {         console.log('Solving the captcha...')         const res = await solver.solveRecaptchaV2(wafParams)         console.log(`Solved the captcha ${res.id}`)         console.log(res)         console.log('Using the token...')         await page.evaluate(token => {           window.localStorage.inputCaptchaToken(token)         }, res.data.captcha.voucher)         console.log(e)       } catch (e) {         console.log(e)       }     }   })    await page.goto(target)   // Additional code to interact with the page after captcha is solved might be here... }  example() 

И второй файл inject.js

console.clear = () => console.log('Console was cleared')  const i = setInterval(() => {   if (window.CaptchaScript) {     clearInterval(i)      let params = gokProps      Array.from(document.querySelectorAll('script')).forEach(s => {       const src = s.getAttribute('src')       if (src && src.includes('captcha.js')) params.captcha_script = src       if (src && src.includes('challenge.js')) params.challenge_script = src     })      console.log('intercepted-params: ' + JSON.stringify(params))   } }, 5)

Естественно, я уточнил у Чата, как мне заставить код работать, на что получил рекомендацию использовать стандартную команду

node index.js

Но я же в этих ваших интернетах уже очень долго и понимаю, что код просто так не заработает, если на компе не установленно нужных библиотек, мой нейроконсультант и тут мне помог

Изучив код, который я дал ему в виде скриншотов, он порекомендовал установить следующие пакеты

puppeteer

2captcha-ts

playwright

Единственно, я не совсем понял, нафига тут нужен playwright, но кто я такой, чтобы сомневаться в компетенции Чата.

И соответсвенно код установки npm install puppeteer 2captcha-ts playwright (правда у меня через VS Code не получилось их поставить все вместе, вероятно виной всему кривые руки, я ставил по одному и через консоль)

npm install puppeteer

npm install 2captcha-ts

npm install playwright

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

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

APIKEY=your_2captcha_api_key

Понятно, что вместо параметра your_2captcha_api_key я подставил свой ключ с сервиса.

Дальше было еще 6 рекомендаций, что надо делать чтобы код заработал, но

Соответсвенно первый запуск и первая ошибка.

Ошибка была связана с использованием синтаксиса ES6 import в Node.js. Для его использования нужно либо указать тип модуля в package.json, либо изменить расширение файла на .mjs.

Мне было лень указывать тип модуля в package.json и я пошел по пути наименьшего сопротивления, тупо переименовал расширение файла index с js на mjs.

Следующая ошибка была связана с подключаемым пакетом 2captcha-ts, но подробно описывать их не хочется, скажу лишь что я изменил код, отвечающий за запуск этого модуля несколько раз, добавил логирование и проверку корректности подключения файла .env.

И это все равно не сработало, скрипт продолжал выдавать ошибку и упорно не хотел работать. Я сравнил скриншот и код который мне вытащил оттуда Чат и нашел небольшую опечатку, которая и была корнем проблемы.

Но, как оказалось, и это не помогло — выпала ошибка APIKEY is not defined in .env file

Это мы пофиксили добавлением нового пакета:

dotenv

npm install dotenv

После этого встреилось еще пару опечаток, которые Чат пытался решить через изменения структуры кода, но надо было просто внимательно сравнить скриншот и сам код.

И в конце концов код файла index.js из вот такого:

// index.js import { launch } from 'puppeteer' import { Captcha } from '2captcha-ts' import { readFileSync } from 'fs'  const solver = new Captcha(process.env.APIKEY)  const target = 'УРЛ сайта где встречается капча'  const example = async () => {   const browser = await launch({     headless: false,     devtools: true   })    const [page] = await browser.pages()    const preloadFile = readFileSync('./inject.js', 'utf8')   await page.evaluateOnNewDocument(preloadFile)    // Here we intercept the console messages to catch the message logged by inject.js script   page.on('console', async (msg) => {     const txt = msg.text()     if (txt.includes('intercepted-params:')) {       const params = JSON.parse(txt.replace('intercepted-params:', ''))        const wafParams = {         pageurl: target,         sitekey: params.key,         iv: params.iv,         context: params.context,         challenge_script: params.challenge_script,         captcha_script: params.captcha_script       }       console.log(wafParams)        try {         console.log('Solving the captcha...')         const res = await solver.solveRecaptchaV2(wafParams)         console.log(`Solved the captcha ${res.id}`)         console.log(res)         console.log('Using the token...')         await page.evaluate(token => {           window.localStorage.inputCaptchaToken(token)         }, res.data.captcha.voucher)         console.log(e)       } catch (e) {         console.log(e)       }     }   })    await page.goto(target)   // Additional code to interact with the page after captcha is solved might be here... }  example()

Превратился в вот такой index.mjs

// index.js import 'dotenv/config'; import { launch } from 'puppeteer' import Captcha from '2captcha-ts'; import { readFileSync } from 'fs'  // Проверка наличия APIKEY в .env if (!process.env.APIKEY) {     console.error("APIKEY is not defined in .env file");     process.exit(1); // Завершение выполнения, если ключ не найден }  const solver = new Captcha.Solver(process.env.APIKEY);  const target = 'УРЛ сайта где встречается капча'  const example = async () => {     const browser = await launch({         headless: false,         devtools: true     })      const [page] = await browser.pages()      const preloadFile = readFileSync('./inject.js', 'utf8')     await page.evaluateOnNewDocument(preloadFile)      // Here we intercept the console messages to catch the message logged by inject.js script     page.on('console', async (msg) => {         const txt = msg.text()         if (txt.includes('intercepted-params:')) {             const params = JSON.parse(txt.replace('intercepted-params:', ''))              const wafParams = {                 pageurl: target,                 sitekey: params.key,                 iv: params.iv,                 context: params.context,                 challenge_script: params.challenge_script,                 captcha_script: params.captcha_script             }             console.log(wafParams)              try {                 console.log('Solving the captcha...')                 const res = await solver.amazonWaf(wafParams)                 console.log(`Solved the captcha ${res.id}`)                 console.log(res)                 console.log('Using the token...')                 await page.evaluate(async (token) => {                     await ChallengeScript.submitCaptcha(token);                     window.location.reload ()                 }, res.data.captcha_voucher);             } catch (e) {                 console.log(e)             }         } else {             return         }     })      await page.goto(target)     // Additional code to interact with the page after captcha is solved might be here... }  example()

В коде выше не забудьте подставить верный урл, где требуется решение (если будете применять).

А из вот такого inject.js

console.clear = () => console.log('Console was cleared')  const i = setInterval(() => {   if (window.CaptchaScript) {     clearInterval(i)      let params = gokProps      Array.from(document.querySelectorAll('script')).forEach(s => {       const src = s.getAttribute('src')       if (src && src.includes('captcha.js')) params.captcha_script = src       if (src && src.includes('challenge.js')) params.challenge_script = src     })      console.log('intercepted-params: ' + JSON.stringify(params))   } }, 5)

В вот такой inject.js

// console.clear = () => console.log('Console was cleared')  let counter = 0; const MAX_ATTEMPTS = 2000; // Примерно 10 секунд при интервале в 5 мс console.log('Начинаем поиск CaptchaScript...');  const i = setInterval(() => {     console.log(`Попытка ${counter}: Проверяем наличие CaptchaScript...`);      if (window.CaptchaScript || counter > MAX_ATTEMPTS) {         clearInterval(i);         if (!window.CaptchaScript) {             console.log('CaptchaScript не найден');         } else {             console.log('CaptchaScript найден');              let params = gokuProps;             Array.from(document.querySelectorAll('script')).forEach(s => {                 const src = s.getAttribute('src');                 if (src && src.includes('captcha.js')) params.captcha_script = src;                 if (src && src.includes('challenge.js')) params.challenge_script = src;             });              console.log('intercepted-params: ' + JSON.stringify(params));         }     }     counter++; }, 5); 

И скрипт заработал. Вот прям совсем. Решил капчу и продолжает ее решать при каждом запуске.

Получается будущее наступило, старик. Но это не точно.

Что вам делать с этой информацией? Ну, блин, мне очень нравиться совет — живи теперь с этим. Но, советы раздавать не хочется. Смотрите сами, может пригодится кому для своих проектов…


ссылка на оригинал статьи https://habr.com/ru/articles/787566/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *