Как обойти капчу с помощью JavaScript

Узнайте, как автоматизировать обход капч с помощью JavaScript и NMPjs

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

Статья описывает процесс обхода капч с использованием JavaScript.

Как решить и обойти капчу с помощью JavaScript

Пример кода создан для того, чтобы показать, как можно использовать API решения капчи для обхода reCAPTCHA, но код также может быть использован для обхода других видов капч.

Создайте функцию, которая будет иметь 2 параметра:

  • Первый параметр — это site key (ключ сайта).
  • Второй параметр — это URL страницы, на которой находится вызов капчи.

Затем мы выполним GET-запрос к конечной точке API 2captcha.com/in.php и предоставим значения для этих параметров:

  • key: Ваш API ключ.
  • method: Установите значение в userrecaptcha.
  • googlekey: Ключ сайта.
  • pageurl: URL страницы с капчей.
  • json: Установите значение в 1, чтобы ответ был в формате JSON.
function solveCaptcha(siteKey, pageUrl){
    //make printing text easier
    let log = (text) => {console.log(text)};
    let logErr = (text) => {console.error(text)};
    //your api key
    const apiKey = "YOUR_API_KEY";
    //make a GET request to 2captcha
    fetch(`https://2captcha.com/in.php?key=${apiKey}
    &method=userrecaptcha&googlekey=${siteKey}&pageurl=${pageUrl}&json=1`)
    .then(response => response.json())
    .then(data => {
        //do something with the data
    })
    .catch(error => {
        logErr('Error:', error);
    });
}

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

На странице API содержится список возможных ошибок и их описания. Как правило, все ошибки должны иметь status of 0.

function solveCaptcha(siteKey, pageUrl){
    const apiKey = "YOUR_API_KEY";
    //make a GET request to 2captcha
    fetch(`https://2captcha.com/in.php?key=${apiKey}
    &method=userrecaptcha&googlekey=${siteKey}&pageurl=${pageUrl}&json=1`)
    .then(response => response.json())
    .then(data => {
        //check if there's an error
        if(!data.status){
            //print out error
            logErr('Error:', (data.error_text !== undefined) ? data.error_text : data.request);
        }else{
            //do something else with the data
        }
    })
    .catch(error => {
        logErr('Error:', error);
    });
}

Если запрос будет успешным, будет возвращён ID запроса, который будет использоваться для отслеживания капчи. Если же запрос окажется неуспешным, будет возвращена ошибка, и нам нужно будет сделать функцию способной обрабатывать ошибки.

Теперь нужно сделать ещё один вызов через 20 секунд к конечной точке API 2captcha.com/res.php с использованием ID запроса и API ключа для проверки статуса капчи (была ли она решена).

Для этого я буду использовать функцию setTimeout, и нужно будет проверить и обработать ошибку(и), если таковая произойдёт в ходе запроса.

function solveCaptcha(siteKey, pageUrl){
    const apiKey = "YOUR_API_KEY";
    //make a GET request to 2captcha
    fetch(`https://2captcha.com/in.php?key=${apiKey}
    &method=userrecaptcha&googlekey=${siteKey}&pageurl=${pageUrl}&json=1`)
    .then(response => response.json())
    .then(data => {
        //check if there's an error
        if(!data.status){
            //print out error
            logErr('Error:', (data.error_text !== undefined) ? data.error_text : data.request);
        }else{
            setTimeout(function(captchaId = data.request){
            //make another call with the ID to get the captcha's status
            fetch(`https://2captcha.com/res.php?key=${apiKey}&action=get&id=${captchaId}&json=1`)
                .then(response => response.json())
                .then(data => {
                    if(!data.status){
                        //print out error
                        logErr('Error:', (data.error_text !== undefined) ? data.error_text : data.request);
                    }else{
                        //do something else with the data
                    }
                })
                .catch(error => {
                    logErr('Error:', error);
                });
            }, 20000);
        }
    })
    .catch(error => {
        logErr('Error:', error);
    });
}

Теперь, спустя 20 секунд, конечная точка должна вернуть токен решённой капчи, если капча была решена, или вернуть текст CAPCHA_NOT_READY, если капча не была решена.

Нужно использовать условный оператор, чтобы проверить, была ли капча решена.

Если она не была решена, мы воспользуемся функцией setTimeout, чтобы повторить запрос через 5 секунд. Если она была решена, используем токен в текстовое поле с идентификатором g-recaptcha-response. Также нужно обработать любые возможные ошибки и вывести тексты, чтобы анализировать прогресс работы решения капчи.

function solveCaptcha(siteKey, pageUrl){
    //make printing text easier
    let log = (text) => {console.log(text)};
    let logErr = (text) => {console.error(text)};
    //your api key
    const apiKey = "YOUR_API_KEY";

    //make a GET request to 2captcha
    fetch(`https://2captcha.com/in.php?key=${apiKey}&method=userrecaptcha
    &googlekey=${siteKey}&pageurl=${pageUrl}&json=1`)
    .then(response => response.json())
    .then(data => {
        log('solving captcha...');
        //check if there's an error
        if(!data.status){
            //print out error
            logErr('Error:', (data.error_text !== undefined) ? 
                data.error_text : data.request);
        }else{
            log("Hurray! A worker has solved the captcha, we're retrieving the token...");
            log("Please wait while we retrieve the token...");
            setTimeout(function(captchaId = data.request){
                //make another call with the ID to get the captcha's status
                fetch(`https://2captcha.com/res.php?key=${apiKey}&action=get&id=${captchaId}&json=1`)
                .then(response => response.json())
                .then(data => {
                    if(!data.status && data.request != "CAPCHA_NOT_READY"){
                        //print out error
                        logErr('Error:', (data.error_text !== undefined) ? data.error_text : data.request);
                    }else if(!data.status && data.request == "CAPCHA_NOT_READY"){
                        log("Attempt to retrieve token failed, trying again in 5 secs...");
                        //repeat request after 5 secs
                        setTimeout(function(captchaId){
                            fetch(`https://2captcha.com/res.php?key=${apiKey}&action=get&id=${captchaId}&json=1`)
                            .then(response => response.json())
                            .then(data => {
                                //check if there's an error
                                if(!data.status){
                                    //print out error
                                    logErr('Error:', (data.error_text !== undefined) ? data.error_text : data.request);
                                }else{
                                    log("Captcha token has been retrieved");
                                    //output token
                                    document.querySelector('#g-recaptcha-response').innerHTML = data.request;
                                    log('captcha solved, you may submit the form');
                                }
                            })
                            .catch(error => {
                                logErr('Error:', error);
                            });
                        }, 5000); //end of step 3
                    }else{
                        log("Captcha token has been retrieved");
                        //output token
                        document.querySelector('#g-recaptcha-response').innerHTML = data.request;
                        log('captcha solved');
                    }
                })
                .catch(error => {
                    logErr('Error:', error);
                });
            }, 20000); //end of step 2
        }
    })
    .catch(error => {
        logErr('Error:', error);
    });//end of step 1
}

Таким образом, если надо решить и обойти Google reCAPTCHA на сайте, вызовите указанную выше функцию, предоставив необходимые параметры, и ожидайте ответа от сервиса.

//get url
const pageUrl = window.location.href;
//get sitekey
const siteKey = document.querySelector('[data-sitekey]').getAttribute('data-sitekey');
//invoke the solve captcha function
solveCaptcha(siteKey, pageUrl);

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

Как решить и обойти капчу с помощью JavaScript используя npm пакет @2captcha/captcha-solver

Вы можете использовать наш npm пакет @2captcha/captcha-solver для взаимодействия с API.

Утановите пакет с помощью npm или yarn.
npm:
npm install @2captcha/captcha-solver

yarn:
yarn add @2captcha/captcha-solver

Создайте инстанс:

import { Solver } from '@2captcha/captcha-solver'
const solver = new Solver(process.env.APIKEY)

Найдите параметры капчи и передайте их в соответствующий метод. В примере кода ниже, демонстрация отправки Сoordinates капчи:

const res = await solver.coordinates({
    body: img,
    textinstructions: 'Puzzle center | Центр пазла',
    imginstructions: instruction
})

После этого примените полученный ответ, в соответсвии с тем как он используется на странице.

Заключительное слово

Статья носит исключительно образовательный характер. Помните о необходимости придерживаться этичных и ответственных практик при работе с сервисом.

Ссылки

Примеры

Поддержка

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