Blog

Postado em em 17 de setembro de 2022

Quebrar Qualquer CAPTCHA com VBA

Quer saber como quebrar qualquer CAPTCHA com VBA? Então vem comigo que eu vou te mostrar como fazer isso com uma API!

Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo!

Quebrar Qualquer CAPTCHA com VBA

Para receber por e-mail o(s) arquivo(s) utilizados na aula, preencha:

Fala, Impressionadores! Na aula de hoje você vai ver como quebrar qualquer CAPTCHA com VBA!

Para quebrar qualquer CAPTCHA com VBA nós vamos utilizar a API anti-captcha que vai auxiliar com esse processo.

Aqui no canal nós já mostramos como trabalhar com API no VBA, como trabalhar com dicionários no VBA e como utilizar a biblioteca selenium (para navegar na internet com VBA).

Então é interessante que você já tenha um pouco de conhecimento, pois vamos utilizar todos esses recursos nessa aula para que você consiga utilizar essa API para quebrar qualquer CAPTCHA.

E aí, curioso para saber como quebrar CAPTCHA com VBA?

Recentemente nós fizemos outros dois posts que complementam muito bem essa aula de hoje e são altamente recomendados para o completo entendimento da aula de hoje. São elas:

Ativando referências específicas

Precisaremos utilizar uma biblioteca específica do Excel/VBA para nos auxiliar na aula de hoje. Ela vai permitir trabalhar com o código objeto dessa aula.

Portanto, precisaremos ativá-la para fazer esses procedimentos a seguir, para que tudo funcione corretamente.

Precisamos primeiramente abrir o ambiente de VBA, a partir do atalho do teclado Alt(+Fn)+F11.

Logo após você terá, com o VBA aberto, que:

  • Ir na guia Ferramentas
  • Optar por “Referências…”
  • Marcar a caixinha correspondente ao “Microsoft WinHTTP Services” (como na foto abaixo) e referente também ao “Microsoft Scripting Runtime”
  • OK

Acessando o site e baixando o módulo JsonConverter

Essencial na aula de hoje, deveremos acessar o link recomendado para baixar o módulo JsonConverter já pronto, que vai auxiliar o código principal da aula de hoje.

Inserir um módulo no VBA e colocando nosso código objeto de estudo

Um código do VBA fica armazenado dentro de um módulo, na maioria das vezes.

Para criá-lo, precisamos:

  • Abrir novamente o VBA (se estiver fechado).
  • Optar pela guia Inserir
  • Escolher “Módulo” (como na foto abaixo), e uma caixa branca se abrirá
Quebrar Qualquer CAPTCHA com VBA

Por padrão, o módulo criado terá o nome de “Módulo 1”.

Com o módulo já existente, colocaremos dentro dele os dois primeiros códigos objetos da aula de hoje.

A seguir teremos o primeiro código, e posteriormente o segundo.

Ele, junto com o segundo código (apresentado posteriormente) vão servir de códigos auxiliares para um central (terceiro), apresentado posteriormente.

Function criarTask(chave_cliente As String, url As String, tipo As String, chave_site As String) As String


Dim requisicao As New WinHttpRequest

Dim resposta As Object

Dim informacoes As New Dictionary, task As New Dictionary


' Definir as informações

' Criar o dicionário e depois converter para JSON

' Modelo

'informacoes = {

'    'clientKey' : apikey,

'    'task' : {

'        "type":tipo,

'        "websiteURL":url,

'        "websiteKey":chave_site

'    }

'};


informacoes("clientKey") = chave_cliente

task("type") = tipo

task("websiteURL") = url

task("websiteKey") = chave_site


Set informacoes("task") = task


' Enviar a requisição

requisicao.Open "POST", "https://api.anti-captcha.com/createTask", True

requisicao.SetRequestHeader "Content-Type", "application/json"

requisicao.Send (JsonConverter.ConvertToJson(informacoes))


' Tratamento de erros

On Error GoTo EsperarInformacoes


PassarEsperarInformacoes:

If requisicao.Status <> 200 Then

    MsgBox "Erro: " & requisicao.ResponseText

    Exit Function

End If


While InStr(requisicao.ResponseText, "taskId") = 0

    Application.Wait (Now + TimeValue("00:00:01"))

Wend


On Error GoTo 0


' Converter o JSON

Set resposta = JsonConverter.ParseJson(requisicao.ResponseText)


criarTask = resposta("taskId")


Exit Function

EsperarInformacoes:

    Application.Wait (Now + TimeValue("00:00:01"))

    Resume PassarEsperarInformacoes

End Function

Explicação e comentários do código (function) acima:

  • Function é definida com os argumentos:
    • “chave_cliente” sendo um texto
    • “url” como um texto
    • “tipo” como um texto
    • “chave_site” como um texto
    • A resposta da function também será um texto
  • Dimensionar:
    • a variável “requisicao” como sendo do tipo um novo objeto do tipo WinHttpRequest, que é um objeto da biblioteca que ativamos, a “Microsoft WinHTTP Services”
    • a variável “resposta” como um objeto
    • as variáveis “informacoes” e “task” como novos dicionários
  • Definir as informações:
    • Associar à chave “clientKey” do dicionário “informacoes” o item representado pela variável “chave_cliente”
    • Associar à chave “type” do dicionário “task” o item representado pela variável “tipo”
    • Associar à chave “websiteURL” do dicionário “task” o item representado pela variável “url”
    • Associar à chave “websiteKey” do dicionário “task” o item representado pela variável “chave_site”
    • Associar à chave “task” do dicionário “informacoes” o item representado pela variável “task” (que de fato vai representar um dicionário – e seus itens – dentro de outro)
  • Enviar a requisição:
    • Configurar o método Open da requisição “requisicao”, colocando o site a ser acessado (que no caso é o site do anticaptcha) para “criar a task”
    • Configurar da forma padrão recomendada pelo código para o método SetRequestHeader
    • Enviar (Send) a requisição utilizando como auxiliar a conversão para formato JSON o que vier do código de conversão para JSON do dicionário “informacoes”
  • Utilizar o tratamento de erros :
    • Temos um primeiro “ponto”, que é o retorno do tratamento de erros, que explicaremos por completo nos próximos passos. Ele se chama “PassarEsperarInformacoes”. O código simplesmente segue a partir dele
    • Se der algum erro, iremos para o “ponto” do código (segundo “ponto”) chamado de “EsperarInformacoes”
    • Testaremos a seguinte condição: o método Status da requisição “requisicao” é diferente de 200 (valor padrão para o sucesso do envio da requisição)? Se sim:
      • Uma mensagem de erro, e sua mensagem própria (ResponseText) de motivo do erro vai ser gerada na tela
      • O código vai ser abortado
      • Caso seja igual a 200 (condição falsa do If), ou seja, sucesso na “requisicao”, o código continua
    • Iniciar uma estrutura de repetição do tipo While, analisando: enquanto NÃO tivermos a presença do texto “taskId” no texto da requisição enviada (resultado da função InStr = 0):
      • Esperaremos 1 segundo
      • Quando tivermos o texto “taskId” (resultado da função InStr > 0) no texto da requisição enviada, seguimos o código
    • A linha “On Error GoTo 0” vai fazer o VBA a retornar para o tratamento de erros padrão do VBA, onde resume em caixas os erros apontados pelo próprio VBA, em relação ao código
    • Configurar a variável “resposta” para receber o resultado da função auxiliar ParseJson, que vai proporcionar a conversão da resposta da requisição em termos de VBA. Algo como:
Quebrar Qualquer CAPTCHA com VBA
  • Armazenar na variável “criarTask” o que for resultante da consulta da chave “taskId” do que está no dicionário de resposta (da requisição, mostrada acima). No exemplo acima, ela vai ter a cara de “7654321”
  • Sair da função, com o comando Exit Function
  • O final do código vai ser o tratamento de erros apresentado lá em cima, que forçará o código a vir para esse “ponto especial”, para fazer ações específicas quando temos um erro esperado:
    • Esperar 1 segundo
    • Voltar para o ponto “PassarEsperarInformacoes” (ponto do código lá em cima)
    • Encerra-se a function (End Function)

OBS: Para saber mais a respeito dos tipos de dados no VBA, visite esse link oficial.

O código apresentado anteriormente (primeiro) tem a função de criar a tarefa (task). Então, essa informação vai ser utilizada em outro código, apresentado mais pra frente na aula de hoje.

Agora vamos para o segundo código de estudo da aula de hoje.

Como falado anteriormente, ele, junto com o primeiro apresentado (acima), vão servir de códigos auxiliares para um central (terceiro), apresentado posteriormente.

Acompanhe com a gente o segundo código e os comentários a respeito dele.

Function pegarResultadoTask(chave_cliente As String, taskId As String) As String


Dim requisicao As New WinHttpRequest

'Dim requisicao As New XMLHTTP60

Dim resposta As Object, informacoesJSON As Object

Dim informacoes As New Dictionary

Dim solucao As String


' Criar o dicionário e depois converter para JSON

' Modelo

'informacoes = {

'    'clientKey' : chave_cliente,

'    'taskId' : taskId

'};


informacoes("clientKey") = chave_cliente

informacoes("taskId") = taskId


'Set informacoesJSON = ConvertToJson(informacoes)


' Enviar a requisição

requisicao.Open "POST", "https://api.anti-captcha.com/getTaskResult", True

requisicao.SetRequestHeader "Content-Type", "application/json"

requisicao.Send (ConvertToJson(informacoes))


' Tratamento de erros

On Error GoTo EsperarInformacoes


PassarEsperarInformacoes:

If requisicao.Status <> 200 Then

    MsgBox "Erro: " & requisicao.ResponseText

    Exit Function

End If


While InStr(requisicao.ResponseText, "status"":""ready") = 0

    Application.Wait (Now + TimeValue("00:00:05"))

    requisicao.Send (ConvertToJson(informacoes))

Wend


On Error GoTo 0


' Converter o JSON

Set resposta = JsonConverter.ParseJson(requisicao.ResponseText)


' Pegar a solução

solucao = resposta("solution")("gRecaptchaResponse")


pegarResultadoTask = solucao

 
Exit Function

EsperarInformacoes:

    Application.Wait (Now + TimeValue("00:00:01"))

    Resume PassarEsperarInformacoes

End Function

Explicação e comentários:

  • Function é definida com os argumentos:
    • “chave_cliente” sendo um texto
    • “taskId” como um texto
    • A resposta da function também será um texto
  • Dimensionar:
    • a variável “requisicao” como sendo do tipo um novo objeto do tipo WinHttpRequest, que é um objeto da biblioteca que ativamos, a “Microsoft WinHTTP Services”
    • as variáveis “resposta” e “informacoesJSON” como objetos
    • a variável “informacoes” como um novo dicionários
    • a variável “solucao” como um texto (String)
  • Definir as informações:
    • Associar à chave “clientKey” do dicionário “informacoes” o item representado pela variável “chave_cliente”
    • Associar à chave “taskId” do dicionário “informacoes” o item representado pela variável “taskId”
  • Configurar a variável “informacoesJSON” como a conversão da variável/dicionário “informacoes” para JSON, através da função auxiliar ConvertToJson
  • Enviar a requisição:
    • Configurar o método Open da requisição “requisicao”, colocando o site a ser acessado (que no caso é o site do anticaptcha) para “pegar a resposta da task”
    • Configurar da forma padrão recomendada pelo código para o método SetRequestHeader
    • Enviar (Send) a requisição utilizando como auxiliar a conversão para formato JSON o que vier do código de conversão para JSON do dicionário “informacoes”
  • Utilizar o tratamento de erros :
    • Temos um primeiro “ponto”, que é o retorno do tratamento de erros, que explicaremos por completo nos próximos passos. Ele se chama “PassarEsperarInformacoes”. O código simplesmente segue a partir dele
    • Se der algum erro, iremos para o “ponto” do código (segundo “ponto”) chamado de “EsperarInformacoes”
    • Testaremos a seguinte condição: o método Status da requisição “requisicao” é diferente de 200 (valor padrão para o sucesso do envio da requisição)? Se sim:
      • Uma mensagem de erro, e sua mensagem própria (ResponseText) de motivo do erro vai ser gerada na tela
      • O código vai ser abortado
      • Caso seja igual a 200 (condição falsa do If), ou seja, sucesso na “requisicao”, o código continua
    • Iniciar uma estrutura de repetição do tipo While, analisando: enquanto NÃO tivermos a presença do texto “status”:”ready” (que é quando temos a resposta da requisição) no texto da requisição enviada (resultado da função InStr = 0):
      • Esperaremos agora 5 segundos (tempo maior devido a um tempo relativamente suficiente para se resolver um CAPTCHA)
      • Quando tivermos o texto “status”:”ready” (resultado da função InStr > 0) no texto da requisição enviada, seguimos o código
    • A linha “On Error GoTo 0” vai fazer o VBA a retornar para o tratamento de erros padrão do VBA, onde resume em caixas os erros apontados pelo próprio VBA, em relação ao código
    • Configurar a variável “resposta” para receber o resultado da função auxiliar ParseJson, que vai proporcionar a conversão da resposta da requisição em termos de VBA
    • Armazenar na variável “solucao” o que for resultante da consulta da chave “gRecaptchaResponse” do que está no dicionário de chave “solution”, dentro do dicionário de resposta, representado pela variável “resposta”. No exemplo, a informação seria representada por:
Quebrar Qualquer CAPTCHA com VBA
  • Armazenar na variável “pegarResultadoTask” o que estiver na variável “solucao”, definida acima
  • Sair da função, com o comando Exit Function
  • O final do código vai ser o tratamento de erros apresentado lá em cima, que forçará o código a vir para esse “ponto especial”, para fazer ações específicas quando temos um erro esperado:
    • Esperar 1 segundo
    • Voltar para o ponto “PassarEsperarInformacoes” (ponto do código lá em cima)
    • Encerra-se a function (End Function)

A seguir, então, vamos ao código central da aula de hoje. Ele vai utilizar dos códigos apresentados anteriormente como auxiliares (pegando informações parciais com cada um dos códigos individuais), e assim desempenhar ações.

Esse terceiro código ficará em outro módulo separado, que criaremos conforme os passos descritos no começo do post de hoje.

Veja a seguir o terceiro código e seus comentários:

Sub consumirAPICaptcha()


Dim url As String, tipo As String, chave_site As String

Dim taskId As String, solucao As String

Dim navegador As New ChromeDriver


navegador.get "https://google.com/recaptcha/api2/demo"

 
' Definir as informações

chave_cliente = "abc123" 'Preencher com a sua chave de cliente

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

tipo = "RecaptchaV2TaskProxyless"

chave_site = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"


' Criar a tarefa

taskId = criarTask(chave_cliente, url, tipo, chave_site)


' Pegar a resposta
solucao = pegarResultadoTask(chave_cliente, taskId)

navegador.ExecuteScript ("document.getElementById('g-recaptcha-response').innerHTML = '" & solucao & "'")
navegador.FindElementById("recaptcha-demo-submit").Click

Set navegador = Nothing

End Sub

Explicação e comentários:

  • Dimensionar:
  • Acessar o link “https://google.com/recaptcha/api2/demo” pelo navegador em questão
  • Armazenar o texto “abc123” na variável “chave_cliente” (REPARE QUE AQUI VOCÊ UTILIZARÁ A SUA CHAVE CLIENTE, adquirida diretamente no site anti-captcha ou em qualquer outro indicado, e a que colocamos aqui no código é apenas uma chave exemplo)
  • Armazenar o link “https://google.com/recaptcha/api2/demo” na variável “url”
  • Armazenar o texto “RecaptchaV2TaskProxyless” na variável “tipo”
  • Armazenar o texto “6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-” na variável “chave_site”
  • Esse texto é o correspondente ao que podemos encontrar no detalhamento do captcha em questão. Dentro do navegador do Google Chrome, com a tecla (Fn+)F12 você consegue procurando pelo “recaptcha-demo”, e copiando o texto vinculado ao item “data-sitekey” (marcado em vermelho abaixo):
  • Criar a tarefa “taskId” a resposta da função criada pelo primeiro código da aula de hoje, a function “criarTask”. Ela vai utilizar os argumentos que armazenamos dentro desse código: as variáveis “chave_cliente”, “url”, “tipo” e “chave_site”
  • Armazenar na variável “solucao” a resposta da função criada pelo segundo código da aula de hoje, a function “pegarResultadoTask”. Ela vai utilizar os argumentos que armazenamos dentro desse código: as variáveis “chave_cliente” e “taskId”
  • Executar o script pelo navegador para colocar dentro da propriedade textual do elemento de ID “g-recaptcha-response” aplicado ao console do navagedor. É nessa etapa que passamos a “solucao” para o “navegador” em relação ao captcha.
  • Clicar no elemento de ID “recaptcha-demo-submit”, que representa o botão da página em questão para “enviarmos” a resposta ao site
  • Vamos esvaziar da memória a variável “navegador”, para que ela não represente mais o objeto
  • Se encerra o código

OBS: O código apresentado acima é um exemplo baseado em outro que apresentamos na aula de APIs (Ler Qualquer API Com VBA)

OBS2: Para tornar possível o completo entendimento do código acima, também é legal que você visite nossa outra aula onde ensinamos como usar o Selenium no VBA para buscar informações na Web

Conclusão – Quebrar Qualquer CAPTCHA com VBA

Hoje você viu como quebrar de CAPTCHA com VBA, e como navegar na internet com VBA!

De quebra aprendeu como ativar referências no VBA, como inserir módulos e lidar com tipos de dados diferentes: dicionários no VBA, além de lidar com a biblioteca Selenium.

Até o próximo post, Impressionadores! Fique ligado no nosso canal do Youtube para mais conteúdo de VBA! Um abraço!

Hashtag Treinamentos

Para acessar outras publicações de VBA, clique aqui!


Quer aprender mais sobre VBA com um minicurso básico gratuito?

Quer sair do zero na linguagem de programação que mais cresce no mundo? Inscreva-se gratuitamente no Intensivão de Python!