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:
Info
Este guia foi construído usando o serviço Anticaptcha como referência.
Consulte mais detalhes acessando a documentação Anticaptcha.