Ir para o conteúdo

Automações Web e Captchas

Encontrar diferentes tipos de captcha durante um processo é uma situação comum quando estamos desenvolvendo automações Web.

Eles podem apresentar diferentes complexidades, tornando necessário usar alternativas diferentes para resolver cada caso.

Este guia demonstrará as alternativas existentes e as maneiras mais fáceis de resolver diferentes tipos de captcha nas automações Web.

Serviços de resolução de captcha

Atualmente, existem vários serviços para resolução de Captchas, geralmente esses serviços oferecem uma API e também uma extensão a ser utilizada no navegador.

O Plugin Botcity Captcha atualmente oferece suporte aos serviços Anticaptcha e DeathBycaptcha, o plugin é baseado no uso da API desses serviços e é apenas uma maneira de facilitar a integração com o seu bot.

Se você tiver uma conta em outro serviço, também é possível integrar ao seu bot. Basta usar o código referente a este serviço em vez de usar o plugin.

Nos exemplos a seguir, usaremos o serviço AntiCaptcha e demonstraremos como podemos usar a API ou a extensão do navegador para resolver Captchas.

Quando usar a API ou extensão navegador?

Como mencionado acima, a maioria dos serviços de resolução de captcha oferece além de uma API, uma extensão a ser usada no navegador.

Abaixo, listamos os prós e contras de cada alternativa:

API

  • Prós:

    • Geralmente a resolução é feita mais rápido
    • Nenhuma configuração do navegador é necessária, basta fazer as chamadas da API
    • Funciona normalmente com ou sem modo headless
    • Melhor alternativa para Captchas de imagem
  • Contras:

    • Algumas limitações para validar captchas invisíveis (hCaptcha ou reCaptcha)
    • Captchas que usam uma função de retorno de chamada pode causar problemas ao injetar a resposta na página

Extensão do navegador

  • Prós:

    • Identifica e resolve o captcha automaticamente
    • Resolve o Captcha de uma maneira mais "humana", é mais difícil ser bloqueado pela página
    • Melhor alternativa para os captchas que usam uma função de retorno de chamada
  • Contras:

    • A resolução do captcha pode demorar um pouco em alguns casos
    • Em alguns casos, pode não funcionar no modo headless (limitação do Chrome)

Resolvendo captchas usando API

A resolução dos captchas usando a API será basicamente dividida em duas etapas.

O primeiro passo é coletar algumas informações da página e fazer a solicitação. A segunda etapa é injetar a resposta que foi retornada à página.

reCaptcha e hCaptcha

Para resolver esses tipos de captcha, geralmente precisamos da propriedade data-sitekey da página. Na maioria dos casos, você pode ver o elemento que contém essa propriedade ao inspecionar a página.

Depois que a API resolver o Captcha, inseriremos o token de resposta na página. Normalmente, essa resposta será injetada no elemento g-recaptcha-response.

from botcity.web import WebBot
from botcity.plugins.captcha import BotAntiCaptchaPlugin


def main():
    bot = WebBot()

    bot.headless = False
    bot.driver_path = r"<chromedriver path>"

    url = "https://www.google.com/recaptcha/api2/demo"

    # Abre o site.
    bot.browse(url)

    # Encontre o elemento com data-sitekey
    captcha_id = bot.find_element('.g-recaptcha').get_attribute('data-sitekey')

    # Usando o plug -in com sua chave de API Anticaptcha
    anti_captcha = BotAntiCaptchaPlugin("<API_KEY>")

    # Resolvendo Captcha
    resposta = anti_captcha.solve_re(url, captcha_id)

    # Inserção de resposta no componente Recaptcha da página
    bot.execute_javascript('document.getElementById("g-recaptcha-response").innerHTML = "%s"' % resposta)

    # Clicando no botão Enviar
    enviar = bot.find_element("#recaptcha-demo-submit")
    enviar.click()

    # Verificando que a resolução funcionou
    assert bot.find_element(".recaptcha-success")
    print("Success!")

    # Pare o navegador e limpe
    bot.wait(3000)
    bot.stop_browser()


def not_found(label):
    print(f"Element not found: {label}")

if __name__ == '__main__':
    main()

Importante

Geralmente, os elementos usados sempre aparecem com estes nomes: data-sitekey eg-recaptcha-response. Observe que a página que você está automatizando também usa esse padrão.

Captcha de Imagem

Para resolver um Captcha de imagem, primeiro precisamos salvar o .png da imagem. Quando a API retornar o resultado, inseriremos na entrada de resposta da página.

from botcity.web import WebBot, By
from botcity.plugins.captcha import BotAntiCaptchaPlugin


def main():
    bot = WebBot()

    bot.headless = False
    bot.driver_path = r"<chromedriver path>"

    # Abre o site
    bot.browse("https://democaptcha.com/demo-form-eng/image.html")

    bot.find_element("message", By.NAME).send_keys("Solving captcha!")

    # Salvando a imagem do captcha
    captcha_img = bot.find_element("htest_image", By.ID)
    captcha_img.screenshot("captcha.png")

    # Usando o plug -in com sua chave de API Anticaptcha
    anti_captcha = BotAntiCaptchaPlugin("<API_KEY>")

    # Resolvendo Captcha
    resposta = anti_captcha.solve_text("captcha.png")

    # Inserção de resposta na entrada
    captcha_input = bot.find_element("vericode", By.ID)
    captcha_input.send_keys(resposta)
    bot.wait(2000)

    # Clicando para verificar Captcha
    enviar = bot.find_element("btn.btn-install", By.CLASS_NAME)
    enviar.click()

    # Pare o navegador e limpe
    bot.wait(5000)
    bot.stop_browser()


def not_found(label):
    print(f"Element not found: {label}")

if __name__ == '__main__':
    main()

Dica

Geralmente a extensão do navegador não identifica esse tipo de captcha automaticamente, portanto, o uso da API é a melhor alternativa para resolver captchas de imagem.

Resolvendo Captchas usando a extensão do navegador

No caso do serviço Anticaptcha, além de usar a API, também é possível usar uma extensão do navegador para resolver o Captchas automaticamente.

Tudo o que precisamos é carregar a extensão e enviar uma mensagem ao navegador para definir a chave da API.

Usando a extensão Anticaptcha com Chrome

A primeira etapa é baixar a extensão .crx do link fornecido pela documentação Anticaptcha.

Aviso

Para poder baixar corretamente o arquivo .crx e evitar bloqueios, o Anticaptcha recomenda o uso de algumas configurações. Veja mais detalhes neste link.

Com o arquivo baixado, vamos inserir a seguinte configuração no código de automação:

from botcity.web import WebBot, By
from botcity.web.browsers.chrome import default_options
import json


def main():
    bot = WebBot()

    bot.headless = False
    bot.driver_path = r"<chromedriver path>"

    # Carregando a extensão .crx
    def_options = default_options()
    def_options.add_extension('anticaptcha-plugin_v0.63.crx')
    bot.options = def_options

    # Abre o site
    bot.browse("https://www.google.com/recaptcha/api2/demo")
    bot.wait(1000)

    # Configuração que será passada para a extensão, ajuste para sua chave de API
    mensagem = {
        'receiver': 'antiCaptchaPlugin',
        'type': 'setOptions',
        'options': {'antiCaptchaApiKey': '<API_KEY>'}
    }
    # Execute o código JS no contexto da página da web e execute uma postagem
    bot.driver.execute_script("""
        return window.postMessage({});
        """.format(json.dumps(mensagem))
    )

    # Refrescando a página para atualizar a configuração
    bot.wait(2000)
    bot.refresh()

    # Resultado da verificação, aguarda a mensagem "resolvida"
    if bot.find_element('.antigate_solver.solved', By.CSS_SELECTOR, waiting_time=180000):
        enviar = bot.find_element("#recaptcha-demo-submit")
        enviar.click()

    # Pare o navegador e o limpe
    bot.wait(3000)
    bot.stop_browser()


def not_found(label):
    print(f"Element not found: {label}")

if __name__ == '__main__':
    main()

Info

Usando o Chrome, também é possível realizar essa configuração manualmente usando o formato .zip da extensão em vez do arquivo.crx.

Consulte mais detalhes sobre como usar a extensão no formato .zip neste link.

Usando a extensão Anticaptcha com Firefox

Usando o Firefox, a configuração que precisamos fazer no navegador é a mesma que no Chrome. A única diferença é que usaremos a extensão no formato .xpi.

Você pode baixar o arquivo .xpi no link fornecido pela documentação Anticaptcha.

from botcity.web import WebBot, Browser, By
import json


def main():
    bot = WebBot()

    bot.headless = False
    bot.browser = Browser.FIREFOX
    bot.driver_path = r"<geckodriver path>"

    # Carregando a extensão .xpi
    bot.install_firefox_extension("anticaptcha-plugin_v0.60.xpi")

    # Abre o site
    bot.browse("https://www.google.com/recaptcha/api2/demo")
    bot.wait(1000)

    # Configuração que será passada para a extensão, ajuste para sua chave de API
    mensagem = {
        'receiver': 'antiCaptchaPlugin',
        'type': 'setOptions',
        'options': {'antiCaptchaApiKey': '<API_KEY>'}
    }
    # Execute o código JS no contexto da página da web e execute uma postagem
    bot.driver.execute_script("""
        return window.postMessage({});
        """.format(json.dumps(mensagem))
    )

    # Refrescando a página para atualizar a configuração
    bot.wait(2000)
    bot.refresh()

    # Resultado da verificação, aguarda a mensagem "resolvida"
    if bot.find_element('.antigate_solver.solved', By.CSS_SELECTOR, waiting_time=180000):
        enviar = bot.find_element("#recaptcha-demo-submit")
        enviar.click()

    # Pare o navegador e limpe
    bot.wait(3000)
    bot.stop_browser()


def not_found(label):
    print(f"Element not found: {label}")

if __name__ == '__main__':
    main()

Executando este código, o resultado ficará assim: ReCaptcha

Info

Este guia foi construído usando o serviço Anticaptcha como referência.

Consulte mais detalhes acessando a documentação Anticaptcha.