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

Как обойти капчу на платформе для парсинга сайтов Diggernaut: Решаем Google reCaptcha v2

Как обойти капчу на платформе для парсинга сайтов Diggernaut: Решаем Google reCaptcha v2

Гугл рекапча (reCaptcha v2) перестала быть проблемой для наших пользователей. Мы внедрили интеграцию с популярным сервисов по обходу капчи Death By Captcha и теперь ваши скраперы могут легко обходить самые современные капчи.

Давайте посмотрим, как выглядит reCaptcha v2:

Обходим капчу: определяем reCaptcha v2

Если вы видите именно такую капчу на сайте. который вам нужно отпарсить, то эта статья вам обязательно поможет. Мы постараемя дать вам исчерпывающее руководство на реальном примере, так, чтобы вы смогли легко внедрить подобное решение для вашего сайта. Мы же будем парсить следующий сайт: http://www.receita.fazenda.gov.br/PessoaJuridica/CNPJ/cnpjreva/Cnpjreva_Solicitacao2.asp.

Для того, чтобы пользовать этим функционалом вам нужно иметь собственный аккаунт в службе Death by Captcha. Их услуги не бесплатны, стоимость решения 100 капч составляет примерно 2.89$ (цена актуальна на 28.02.2018).

Решение капчи происходит автоматически, вам нужно лишь загрузить страницу с капчей в ваш скрапер и вызвать специальную команду captcha_resolve с определенными параметрами:

prodiver: провайдер решений для капчи, нужно установить значение deathbycaptcha.com
type: тип капчи, нужно установить значение nocaptchav2
username: имя пользователя вашего аккаунта в системе death by captcha
password: пароль вашего аккаунта в системе death by captcha

ВНИМАНИЕ!!! Для того чтобы капча этого типа была успешно решена, люди, которые будут вручную решать вашу капчу должны будут это делать под тем же IP адресом, что использует ваш парсер. Поэтому, единственный вариант этого достичь — использовать ВАШ СОБСТВЕННЫЙ ПРОКСИ СЕРВЕР в конфигурации вашего диггера. Наши штатные прокси сервера не могут быть доступны с IP адресов, вне нашей основной сети, поэтому штатные прокси просто не будут работать в этом случае. В дальнейшем мы внедрим специальный пул прокси серверов для этой задачи, но пока вы должны будете использовать свой прокси.

Базовый код нашего парсера будет таким:

---
config:
    debug: 2
    agent: Firefox
    proxy: ВАШ ПРОКСИ НУЖНО ВСТАВИТЬ СЮДА
do:
# Мы будем повторять неудавшийся запрос, поэтому пропишем значение переменной,
# которую будет использовать опция repeat
- variable_set:
    field: repeat
    value: "yes"
# Загружаем страницу с капчей
- walk:
    to: http://www.receita.fazenda.gov.br/PessoaJuridica/CNPJ/cnpjreva/cnpjreva_solicitacao2.asp
    repeat: <%repeat%>
    do:
        # Решаем капчу
    - captcha_resolve:
        provider: deathbycaptcha.com
        type: nocaptchav2
        username: ВАШЕ ИМЯ ПОЛЬЗОВАТЕЛЯ В СЛУЖБЕ DBC
        password: ВАШ ПАРОЛЬ В СЛУЖБЕ DBC

Пока не запускайте ваш парсер, просто изучите код. Если капча решена успешно, токен будет сохранен в переменной captcha. Поэтому, первым делом после решения капчи мы должны проверить наличие токена в переменной. Если токен есть, мы отключим опцию repeat и передадим токен на сервер вместе с другими параметрами нашего запроса. Если токена нет, запрос будет повторен, поскольку опция repeat установлена в «yes».

---
config:
    debug: 2
    agent: Firefox
    proxy: ВАШ ПРОКСИ НУЖНО ВСТАВИТЬ СЮДА
do:
# Мы будем повторять неудавшийся запрос, поэтому пропишем значение переменной,
# которую будет использовать опция repeat
- variable_set:
    field: repeat
    value: "yes"
# Загружаем страницу с капчей
- walk:
    to: http://www.receita.fazenda.gov.br/PessoaJuridica/CNPJ/cnpjreva/cnpjreva_solicitacao2.asp
    repeat: <%repeat%>
    do:
    # Решаем капчу
    - captcha_resolve:
        provider: deathbycaptcha.com
        type: nocaptchav2
        username: ВАШЕ ИМЯ ПОЛЬЗОВАТЕЛЯ В СЛУЖБЕ DBC
        password: ВАШ ПАРОЛЬ В СЛУЖБЕ DBC
    # Переходим в блок body
    - find:
        path: body
        do:
        # Читаем значение переменной captcha в регистр
        - variable_get: captcha
        # Проверяем, не пустой ли у нас регистр
        - if:
            match: \w+
            do:
            # Если не пустой, отключаем repeat
            - variable_set:
                field: repeat
                value: "no"
            # Передаем токен и другие параметры на сайт с которого мы собираем информацию.
            # В данном случае мы пытаемся получить данные о компании по его ИНН (CNPJ)
            - walk:
                to:
                    post: http://www.receita.fazenda.gov.br/PessoaJuridica/CNPJ/cnpjreva/valida_recaptcha.asp
                    data:
                        origem: comprovante
                        cnpj: 05754558000186
                        g-recaptcha-response: <%captcha%>
                        submit1: Consultar
                        search_type: cnpj
                do:
                - find:
                    path: 'div#principal'
                    do:
                    - object_new: item
                    - find:
                        path: td:haschild(font:contains('NÚMERO DE INSCRIÇÃO')) b
                        slice: 0
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_set:
                            object: item
                            field: registration_number
                    - find:
                        path: td:haschild(font:contains('DATA DE ABERTURA')) b
                        slice: 0
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_set:
                            object: item
                            field: registration_date
                    - find:
                        path: td:haschild(font:contains('NOME EMPRESARIAL')) b
                        slice: 0
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_set:
                            object: item
                            field: company_name
                    - find:
                        path: td:haschild(font:contains('CÓDIGO E DESCRIÇÃO DA ATIVIDADE ECONÔMICA PRINCIPAL')) b
                        slice: 0
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_set:
                            object: item
                            field: primary_code
                    - find:
                        path: td:haschild(font:contains('CÓDIGO E DESCRIÇÃO DAS ATIVIDADES ECONÔMICAS SECUNDÁRIAS')) b
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_push:
                            object: item
                            field: secondary_codes
                    - find:
                        path: td:haschild(font:contains('CÓDIGO E DESCRIÇÃO DA NATUREZA JURÍDICA')) b
                        slice: 0
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_set:
                            object: item
                            field: legal_code
                    - find:
                        path: td:haschild(font:contains('LOGRADOURO')) b
                        slice: 0
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_set:
                            object: item
                            field: street
                    - find:
                        path: td:haschild(font:contains('BAIRRO/DISTRITO')) b
                        slice: 0
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_set:
                            object: item
                            field: district
                    - find:
                        path: td:haschild(font:contains('MUNICÍPIO')) b
                        slice: 0
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_set:
                            object: item
                            field: municipal
                    - find:
                        path: td:haschild(font:contains('TELEFONE')) b
                        slice: 0
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_set:
                            object: item
                            field: phone
                    - find:
                        path: td:haschild(font:contains('E-MAIL')) b
                        slice: 0
                        do:
                        - parse
                        - space_dedupe
                        - trim
                        - object_field_set:
                            object: item
                            field: email
                    - object_save:
                        name: item

Если вы запустите этот парсер вы получите следующий датасет

[{
    "item": {
        "company_name": "LIST - LOGISTICA INTEGRADA, SERVICOS E TRANSPORTES LTDA",
        "district": "COROADO",
        "legal_code": "206-2 - Sociedade Empresária Limitada",
        "municipal": "MANAUS",
        "phone": "(92) 3622-7885",
        "primary_code": "52.12-5-00 - Carga e descarga",
        "registration_date": "26/06/2003",
        "registration_number": "05.754.558/0001-86",
        "secondary_codes": [
            "49.30-2-02 - Transporte rodoviário de carga, exceto produtos perigosos e mudanças, intermunicipal, interestadual e internacional",
            "77.39-0-99 - Aluguel de outras máquinas e equipamentos comerciais e industriais não especificados anteriormente, sem operador",
            "77.19-5-99 - Locação de outros meios de transporte não especificados anteriormente, sem condutor",
            "52.29-0-99 - Outras atividades auxiliares dos transportes terrestres não especificadas anteriormente",
            "49.30-2-01 - Transporte rodoviário de carga, exceto produtos perigosos e mudanças, municipal",
            "52.50-8-03 - Agenciamento de cargas, exceto para o transporte marítimo"
        ],
        "street": "R PROFESSORA RAYMUNDA MAGALHAES"
    }
}]

Подобные решения часто используются в сценариях типа «Данные по требованию». Когда пользователь на вашем сайте вводит номер, ваш сайт принимает ввод от пользователя и делает запрос на API платформы Diggernaut. Этот запрос запускает диггер с переданным параметром и возвращает собранные данные обратно на ваш сервер в режиме реального времени. А ваш сервер показывает их вашему пользователю. Однако примите во внимание, что процесс решения капчи может занимать продолжительное время, например решение reCaptcha v2 может занимать более 1 минуты. Это нужно учитывать при проектировании вашего приложения.

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

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

6 Replies to “Как обойти капчу на платформе для парсинга сайтов…”

    1. Пока нет решения для ReCaptcha v3, как только оно появится, мы оповестим всех через блог и сделаем изменения в документации

    2. Появилось решение для ReCaptcha V3. Его предоставляет сервис RuCaptcha/2Captcha. Интеграция с ними была выпущена вчера. Больше информации можно найти в документации

    1. У нас в данный момент есть интеграции с DeathByCaptcha и Anti-Captcha. Посмотрим в сторону RuCaptcha, если у них все нормально с API, добавим и их.

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

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

Этот сайт защищен reCAPTCHA и применяются Политика конфиденциальности и Условия обслуживания применять.

Срок проверки reCAPTCHA истек. Перезагрузите страницу.