воскресенье, 28 августа 2016 г.

Разгадывание reCaptcha с помощью java, phantomjs, jsoup и сервиса rucaptcha

     Есть 2 способа разгадывания recaptcha v2 (выбор картинок по параметрам): когда есть кнопка submit (например, при авторизации на сайте) и когда она отсутствует (при постинге на стене vk). Рассмотрим сначала первый и более простой вариант с кнопкой

     1. С наглядными и подробными пояснениями можно ознакомиться на оф. сайте рукапчи КЛАЦ. Я же объясню, как это сделать с помощью java
      Импортируем библиотеки phantomjs, jsoup и commons-lang
<dependency>
    <groupId>com.codeborne</groupId>
    <artifactId>phantomjsdriver</artifactId>
    <version>1.3.0</version>
</dependency>
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.7.2</version>
 </dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.4</version>
 </dependency>
Как настроить phantomjs я уже писал ТУТ.

        //1. Получаем google code капчи
        String src = driver.findElement(By.tagName("iframe")).getAttribute("src");
        String googleCode = StringUtils.substringBetween(src, "?k=", "&");

        //2. Получаем id капчи от сервиса рукапчи
            document = Jsoup.connect("http://rucaptcha.com/in.php?key=КЛЮЧ СЕРВИСА РУКАПЧИ&method=userrecaptcha&googlekey="+googleCode).get();
        String captchaId = StringUtils.substringAfter(document.text(), "OK|");

        //3. Ждем разгаданную капчу от сервиса рукапчи, делая запрос каждые 5 секунд
       String documentText;
        do {
            Thread.sleep(5000);
            document = Jsoup.connect("http://rucaptcha.com/res.php?key=КЛЮЧ СЕРВИСА РУКАПЧИ&action=get&id="+captchaId).get();
            documentText = document.text();
        } while (!documentText.contains("OK"));
        String captchaResponse = StringUtils.substringAfter(documentText, "OK|");

        //4. Делаем элемент g-recaptcha-response видимым
        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("document.getElementById('g-recaptcha-response').setAttribute('style', '')");

        //5. Вводим ответ от сервиса в текстовое поле, которое сделали видимым в предыдущем пункте
        driver.findElement(By.id("g-recaptcha-response")).sendKeys(captchaResponse);

        //6. Нажимаем кнопку отправки формы
        driver.findElement(By.id("submit button id")).click();

     На этом первый способ разгадывания завершен.  При втором способе, придется нажимать на картинки.

     2. Рассмотрим второй способ разгадывания капчи
     Для этого необходимо скачать и подключить jar библиотеку для взаимодействия с api rucaptcha.com ТУТ
     Теперь, если нам попалась капча, делаем следующее:
        //Переключаемся на фрейм с капчей и жмем кнопку "я не робот"
        driver.switchTo().frame("undefined");
        driver.findElementByClassName("recaptcha-checkbox-checkmark").click();

        //После чего отключаемся от этого фрейма и подключаемся к фрейму с картинкой
        driver.switchTo().defaultContent();
        WebElement elementByXPath = driver.findElementByXPath("//iframe[contains(@title,'проверка recaptcha')]");
        driver.switchTo().frame(elementByXPath);
     
        //Получаем текст инструкции, url картинки и список квадратов на которые она разбита
        String src = driver.findElementByXPath("//img[contains(@class,'rc-image-tile-')]").getAttribute("src");
        Document parse = Jsoup.parse(driver.getPageSource());
        String instruction= parse.select(".rc-imageselect-desc-no-canonical").first().text();
        List<WebElement> elements = driver.findElementByXPath("//table[contains(@class,'rc-imageselect-table-')]").findElements(By.className("rc-image-tile-wrapper"));

        //сохраняем капчу локально
        File file = new File("captcha.jpg");
        URL url = new URL(src);
        FileUtils.copyURLToFile(url, file);

        // Определяем размерность сетки (может, размерностей больше, но  пока я встречал              только  три типа)
        int columns;
        int rows;
        if (elements.size()==8){
            rows = 4;
            columns = 2;
        } else if (elements.size()==9){
            rows = 3;
            columns = 3;
        } else {
            rows = 4;
            columns = 4;
        }
   
        //Ждем индексы картинок, по которым нужно кликнуть
        RuCaptcha.API_KEY = "КЛЮЧ СЕРВИСА";
        String captchaID = RuCaptcha.postReCaptcha2(file, instruction, 1, columns, rows);
        captchaID = StringUtils.substringAfter(captchaID, "OK|");
        String resp;
        do {
            Thread.sleep(5000);
            resp = RuCaptcha.getDecryption(captchaID);
        } while (!resp.contains("OK"));
        String indicesStr = StringUtils.substringAfter(resp, "OK|");
        String[] indicesArr = indicesStr.split(":")[1].split("/");

        //кликаем по полученным индексам, после каждого клика выжидая небольшую паузу
        for (String strSquareInd : indicesArr) {
            int intSquareInd = Integer.parseInt(strSquareInd );
             elements = driver.findElementByXPath("//table[contains(@class,'rc-imageselect-table-')]").findElements(By.className("rc-image-tile-wrapper"));
            elements.get(intSquareInd -1).click();
            Thread.sleep(1000);
        }

        // Жмем кнопку подтвердить, после чего наш пост спокойно добавляется в группу vk
        driver.findElementById("recaptcha-verify-button").click();

8 комментариев:

  1. Кирилл (извините если я неправильно обращаюсь к Вам). Сейчас я пишу статью по решению recaptcha c помощью сервиса 2captcha/rucaptcha. Я там приведу код на python для автоматизации решения recaptcha. Можно ли мне привести также ваш код на java для решения recaptcha c помощью сервиса rucaptcha с моими комментариями на английском? Готов привести ссылку на вашу статью. Игорь. igor.savinkin@gmail.com

    ОтветитьУдалить
  2. Также мы могли бы сотрудничать в плане публикаций на сайте.

    ОтветитьУдалить
  3. Первым делом нужно скачать jar-библиотеку с этого сайта.
    Подключить библиотеку к проекту.
    И импортировать ее .

    Как это сделать? Куда импортировать? Как подключить?

    ОтветитьУдалить
    Ответы
    1. Это статья с решением конкретной задачи, а не обучалка по джаве)
      Для сборки проекта использую maven, если это поможет, все остальные вопросы гуглите

      Удалить
  4. Очень хорошая статья, большое спасибо!

    ОтветитьУдалить