Arquivo da categoria: Web

Opiniões sobre tendências e o que anda acontecendo com este mundo desconhecido que é a internet, se é que isso é possível!

Selenium VBA – Como extrair dados de frames

Pois é, Selenium, olha ele aqui de novo. Fazer o quê? Nos o amamos! 🙂

Eis mais uma dúvida que assola o pessoal que se aventura a brincar com Selenium e dá de cara com sites pra lá de complicados. E claro, quando aparecem os frames… bem, sorte sua! No vídeo abaixo demonstro como fazer para extrair os dados de um site com frames, no caso, meu antigo site (muita vergonha aqui).

Confira o vídeo e logo abaixo o código utilizado:

Public Sub ObterDadosDoMeuSiteAntigo()
    Dim driver As New ChromeDriver
 
    driver.Get "http://www.tomasvasquez.com.br/_index.htm"
 
    Debug.Print "Frames encontrados no documento pai: " & driver.FindElementsByTag("frame").Count
 
    Call driver.SwitchToFrame("principal")
 
    Debug.Print "Frames encontrados no frame principal: " & driver.FindElementsByTag("frame").Count
 
    Dim itens As WebElements, item As WebElement
    Set itens = driver.FindElementsByTag("li")
 
    Debug.Print "Itens encontrados:"
    For Each item In itens
        Debug.Print item.Text
    Next item
 
    driver.SwitchToDefaultContent
 
    Debug.Print "Frames encontrados no documento pai: " & driver.FindElementsByTag("frame").Count
 
    driver.Quit
End Sub

Vídeo – Migrando para o Selenium VBA

É, o Selenium fez barulho na comunidade do VBA. Pelo menos isso foi o que deu pra sentir, refletido tanto em questões no fórum, como em comentários no youtube e pedidos de serviço.

O fato é que o selenium tem crescido muito enquanto biblioteca e não só para o VBA. Tudo está muito bem explicado numa série de vídeos que gravei, de comentários a tutoriais (links no fim do artigo).

Por fim, como um auxílio para a migração do SeleniumVBA para o SeleniumBasic, explicado no vídeo “Selenium Basic Já”, gravei mais um tutorial com uma pincelada no código utilizando a nova biblioteca, que você confere abaixo:

Abaixo também segue o código utilizado para referência.

Dim driver As WebDriver
 
Sub ConsultaODolar()
    Set driver = New ChromeDriver
 
    driver.Get "http://www.dolarhoje.com"
 
    Dim nacional As WebElement
    Set nacional = driver.FindElementById("nacional")
 
    If nacional Is Nothing Then
        MsgBox "Elemento não encontrado"
    Else
        MsgBox nacional.Value
    End If
 
    driver.Quit
End Sub
 
Sub VaiProGoogle()
    Set driver = New ChromeDriver
 
    driver.Get "http://www.google.com"
    Application.Wait Now + TimeValue("00:00:01")
 
    Dim busca As WebElement, form As WebElement
    Set busca = driver.FindElementById("lst-ib")
    Set form = driver.FindElementById("tsf")
 
    If Not busca Is Nothing Then
        busca.SendKeys InputBox("Sua busca", "Google", "")
        form.Submit
    Else
        MsgBox "Elemento não encontrado"
    End If
End Sub

Bom proveito!

Usando o Selenium VBA para extrair informações da Web
https://www.youtube.com/watch?v=hk-65p2ivvQ&t=47s

Atualizando o ChromeDriver manualmente para o SeleniumBasic
https://www.youtube.com/watch?v=8fFnr-hmTW8

Selenium Basic já!
https://www.youtube.com/watch?v=WLP7QqgS8CA

Outros Links

SeleniumBasic
https://florentbr.github.io/SeleniumBasic/

ChromeDriver
https://sites.google.com/a/chromium.org/chromedriver/

VBA – Obtendo dados da Web e Serviços Web usando WinHTTP

Estendendo a série de artigos VBA + Web, lembrando que liberei tem pouco tempo um tutoria de Selenium VBA para o quase-mesmo propósito, este tutorial trata de como extrair informações da páginas web e principalmente serviços web, ou web services, como são mais conhecidos.

Para promover a façanha, faremos uso da biblioteca WinHTTP. Em resumo, é ela quem fornece funções para que através de nossos aplicativos no Windows, possamos acessar conteúdo através do protocolo HTTP. Isso significa tudo, ou seja, GET, POST, PUT, DELETE e tudo mais que o protocolo oferecer. Como o mais comum é o GET, vamos começar por ele.

Se você não está familiarizado com estas opções que são chamadas de “verbos”, toda vez que você trafega alpo pela internet, um deste verbos é utilizado. O GET, que na tradução literal do inglês significa “obter”, é exatamente o que acontece quando você digita um endereço de uma página na internet no seu navegador, não importa o qual e clica em Enter.

Vamos fazer isso acontencendo via código:

Sub http()
    Dim MyRequest As Object
 
    'coloca a instância do WinHTTP na memória
    Set MyRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
    MyRequest.Open "GET", "http://www.tomasvasquez.com.br"
 
    'Faz a requisição
    MyRequest.Send
 
    'obtém o conteúdo da resposta e coloca na janela de verificação imediata 
    Debug.Print MyRequest.ResponseText
 
End Sub

O que vai acontecer aqui é a obtenção (verbo GET) de todo o conteúdo que o endereço informado, no caso, o www.tomasvaquez.com.br. Como estamos fazendo uma requisição ao documento padrão, que no caso é um HTML, é isto que veremos na janela do VBA, como mostrado abaixo:

vba_winhttp_tomasvasquez

Como mostrado acima, o resultado é um longo texto que representa o código HTML da página. Você verá a mesma coisa caso acesse o mesmo endereço no seu navegador e mandar exibir o código fonte.

Com isso, podemos começar a imaginar o que é possível fazer a partir desta biblioteca. Apesar de ser possível simular uma navegação em determinados sites, este não é o uso mais indicado para esta biblioteca. O mais adequado é fazer seu uso quando for preciso integrar com serviços REST, o que está mais do que na moda atualmente.

Para deixar o exemplo mais completo, vou usar o RSS do fórum e a partir dele, extrair quais foram as últimas postagens:

Sub UltimasDoForum()
    Dim MyRequest As Object, _
    resposta As String, _
    respostaParcial As String, _
    retorno As Long, _
    stringTitulo As String, _
    fimTitulo As Long
 
    'coloca a instância do WinHTTP na memória
    Set MyRequest = CreateObject("WinHttp.WinHttpRequest.5.1")
    MyRequest.Open "GET", "http://www.tomasvasquez.com.br/forum/feed.php"
 
    'Faz a requisição
    MyRequest.Send
 
    'obtém o conteúdo da resposta
    resposta = MyRequest.ResponseText
 
    stringTitulo = ""
    'procura pelo título do post, se houver
    retorno = InStr(1, resposta, stringTitulo, vbTextCompare)
 
    'itera até o próximo e até não encontrar mais
    While retorno > 0
        fimTitulo = InStr(retorno, resposta, "", vbTextCompare)
        respostaParcial = Left(resposta, fimTitulo)
        Debug.Print Right(respostaParcial, Len(respostaParcial) - retorno - Len(stringTitulo))
        resposta = Right(resposta, Len(resposta) - fimTitulo)
        retorno = InStr(retorno, resposta, stringTitulo, vbTextCompare)
    Wend
End Sub

Não é preciso dar atenção ao código que extrai o texto pois é apenas um tratamento de strings para limpar o código XML. O resultado pode ser visto na figura abaixo:

Macro Ultimas do Forum executada

Ainda haveria que limpar um pouco as strings, mas já é possível ter uma ideia do que é possível começar a fazer com essa biblioteca.

Agora, é com vocês. Bom proveito!

Download do arquivo:

WinHTTP.zip (13.18 KiB)

Referências:

WinHTTP: https://msdn.microsoft.com/pt-br/library/windows/desktop/aa382925%28v=vs.85%29.aspx

VBA – Interagindo com páginas Web com o Selenium WebDriver

Selenium Logo

Introdução

Tem um tempo que publiquei aqui neste blog um artigo sobre como manipular uma página de internet no navegador através do VBA usando o Internet Explorer (este aqui: https://www.tomasvasquez.com.br/blog/microsoft-office/vba-interagindo-com-o-objeto-internet-explorer).

Foi um exemplo simples, mas como o interesse por extração de informações de páginas cresceu tremendamente, o artigo gerou enorme interesse e as discussões no forum afloraram, principalmente com problemas relacionados ao assunto.

O fato é que, o VBA nunca foi muito amigo de integração com a internet. O único recurso que os programadores VBA tinham em mãos era a integração com o Internet Explorer, onde a navegação era simulada para que os dados pudessem ser extraídos. Porém, a internet evolui em uma velocidade insana e como pudemos acompanhar, o Internet Explorer não seguiu nessa velocidade. Isso é tão verdade que a Microsoft vai descontinuar o navegador para lançar em seu lugar o Edge, que vem junto com o Windows 10. Como se isso já não fosse razão suficiente para procurar alternativas, o IE demonstrava certas limitações na simulação da navegação, algumas páginas já não rodavam e o IE11 quebrava uma série de funções.
Já tinha passado da hora de existir outra opção para o feito de extrair informações de páginas da web.

O que é o Selenium

E é aqui que entra o Selenium. O Selenium nasceu como um plugin de automação de rotinas em um browser. Para um programador VBA, é fácil entender o Selenium como se fosse o VBA do Navegador. Com ele, você pode programar, automatizar e até mesmo gravar algo parecido com macros, onde o Selenium grava todas as interações que você realiza em uma página para poder executar depois, podendo inclusive efetuar alterações no código.

Origem

O Selenium veio primeiramente auxiliar na automação de rotinas no navegador, começando pelo Firefox. Ele é até hoje um plugin ou extensão do navegador Firefox chamada Selenium IDE. Com o passar do tempo, o pessoal de testes tomou gosto pelas funcionalidades do Selenium, já que muitas das tarefas de navegação podiam ser automatizadas e repetidas, reduzindo o esforço e a possibilidade de erros drasticamente. O Selenium ganhava uma identidade no mercado de desenvolvimento de software que foi explorada em seguida pelos desenvolvedores.

A criação do WebDriver

Nos últimos anos, a disciplina de Testes de Software ganhou força. É só procurar por artigos e materiais nas redes e sites especializados. Com isso, os testes automatizados por software vieram logo em seguida. Nem é preciso ir muito longe. As “novas linguagens” já nascem quase preparadas para esse tipo de rotina e as que já estavam no mercado se adaptaram para isso.

O Selenium WebDriver veio para entregar aos programadores uma biblioteca que permite através de programação manipular o navegador para automatizar a navegação. Atualmente, o Selenium WebDriver oferece suporte a linguagens como Ruby, C#, Java, Python, Javascript e…. VBA! E é aqui prezados leitores que mora nosso interesse nesta ferramenta.

Instalando

Sim, é possível manipular o Selenium através de código VBA. Primeiro, é preciso instalar o Selenium-VBA, que é a versão da biblioteca que permite a manipulação o Selenium pelo código no VBA.

O Selenium-VBA é gratuito e vem sendo mantido como código aberto, por isso, vem tendo constantes mudanças e pode em alguns casos sofrer com instabilidades.

Estou usando o Selenium-VBA que pode ser baixado neste link:

https://code.google.com/p/selenium-vba/

A versão exata usada para este artigo foi:

http://dl.bintray.com/florentbr/generic/SeleniumWrapperSetup-1.0.23.0.exe

Ao finalizar a instalação, a última tela pergunta se você quer instalar o plugin do Selenium IDE no navegador Firefox. Isso é opcional, mas como é possível extrair muita informação útil do plugin, recomendo que o instale.

Exemplo no VBA

Como iniciei o artigo mencionando a interação com o Internet Explorer, vou replicar o mesmo exemplo utilizando o Selenium VBA.

Comece abrindo o Excel numa nova planilha, abra o Editor do VBA (Alt+F11) e comece adicionando a Referência à biblioteca “SeleniumWrapper Type Library”.

Referências no VBA

Se essa opção não aparecer, verifique a instalação do Selenium.
Em seguida, adicione um novo módulo no VBA (Menu Inserir->Módulo e adicione o seguinte código)

Public driver As New SeleniumWrapper.WebDriver
 
Public Sub AbreELogaNoForum()
    Dim MyPass As String, MyLogin As String
redo:
    MyLogin = Application.InputBox("Por Favor entre com o Login", "Forum Tomás Vásquez", Default:="login", Type:=2)
    MyPass = Application.InputBox("Por favor entre com a senha", "Forum Tomás Vásquez", Default:="Password", Type:=2)
    If MyLogin = "" Or MyPass = "" Then GoTo redo
    driver.Start "chrome", "http://www.tomasvasquez.com.br/"
    driver.setImplicitWait 5000
 
    driver.Open "/forum/ucp.php?mode=login"
    driver.findElementById("username").SendKeys MyLogin
    driver.findElementById("password").SendKeys MyPass
    driver.findElementByName("login").Click
 
End Sub
 
Public Sub FechaBrowser()
    driver.stop
End Sub

Para este exemplo, escolhi o Chrome, que explicarei depois o motivo. Se tudo der certo, o código vai pedir que você digite o usuário e senha do fórum (válidos). Após isso, o Chrome se abrirá, navegará até a página de login de fórum, entrará com suas credenciais e tentará fazer o login na página.

Ok, isso é pouco. Pois bem, vamos tentar explorar um pouco mais do que o Selenium WebDriver pode fazer por nós. Vou mudar a funcão AbreELogaNoForum para além de logar no fórum, navegar até a Pesquisa padrão do fórum e procurar por ocorrências com as palavras “Internet Explorer” e retornar o resultado na tela. Veja como ficou abaixo:

Public Sub AbreELogaNoForum()
 Dim MyPass As String, MyLogin As String
redo:
 MyLogin = Application.InputBox("Por Favor entre com o Login", "Forum Tomás Vásquez", Default:="login", Type:=2)
 MyPass = Application.InputBox("Por favor entre com a senha", "Forum Tomás Vásquez", Default:="Password", Type:=2)
 If MyLogin = "" Or MyPass = "" Then GoTo redo
 driver.Start "chrome", "http://www.tomasvasquez.com.br/"
 driver.setImplicitWait 5000
 
 driver.Open "/forum/ucp.php?mode=login"
 driver.findElementById("username").SendKeys MyLogin
 driver.findElementById("password").SendKeys MyPass
 driver.findElementByName("login").Click
 
 driver.setImplicitWait 1000
 'navega até a pesquisa
 driver.Open "/forum/search.php"
 driver.setImplicitWait 2000
 'digita o critério e pesquisa
 driver.findElementById("keywords").SendKeys "Internet Explorer"
 'procura o botão de Pesquisar através de CSS Selector e clica
 driver.findElementByCssSelector("[value=Pesquisar]").Click
 driver.setImplicitWait 2000
 'obtem o resultado e joga num MsgBox
 MsgBox driver.findElementByClassName("searchresults-title").Text
 
End Sub

Explicando o código, entre uma navegação e outra chamo a função driver.setImplicitWait, que recebe como parâmetro a quantidade de milisegundos (1000 milisegundos = 1 segundo) que a rotina deve esperar antes de executar a próxima instrução. Isso é necessário pois a velocidade de transição entre uma página e outra depende de muitos fatores, desde a velocidade do computador até a velocidade da internet. Ajuste-o para cada caso.

Aqui o resultado foi o seguinte:

Resultado da pesquisa no fórum

Note que neste código, já começamos a explorar funcionalidades inerentes ao HTML5, como seletores complexos de CSS para alcançar determinados elementos.

Obviamente, este é um exemplo que está longe de explorar o potencial do que o Selenium pode fazer. O intuito aqui foi apresentar uma alternativa ao Internet Explorer para automatizar a navegação em páginas da web. Explorarei mais opções de navegação e do Selenium em outros artigos.

Curiosidades

Apesar do Selenium ter nascido com o Firefox, na versão utilizada neste artigo o mesmo dá erro. O bug é conhecido da comunidade do Selenium e está em análise. Até a presente data, mesmo na última versão o erro não havia sido corrigido. O Internet Explorer também pode ser utilizado se for o caso. Não testei com o Microsoft Edge.

A escolha pelo Chrome deve-se ao fato do navegador ser baseado Chromium, que é de código aberto. Com isso, a quantidade de customizações e configurações é enorme e pode ser melhor explorada do que nas alternativas.

Cuidados

Sempre que você o utiliza o Selenium WebDriver, uma instância do “Driver” é criada em memória. Note que o código é divido em 2 funções, sendo uma que abre o navegador e outra que o fecha. Esta última é necessária, por mesmo que você feche o Excel e o navegador, a instância do Driver ficará em memória.

Por fim, não utilize para fins impróprios, como inundar a internet com lixo, automatizando a entrada de dados. Primeiramente, recorra ao bom senso. Depois, a internet é rastreável e é fácil chegar até o causador do problema.

Finalizando

O Selenium é “A”alternativa à automação de navegação web e extração de dados para os programadores VBA. Já utilizei em alguns projetos para clientes e funcionou muito bem, chegando a fazer desde navegação avançada até extração de dados e automação de download de arquivos. Logo publicarei outras opções de código que a biblioteca Selenium Webdriver oferece de customizações para melhor demonstrar o potencial da ferramenta.

Bom proveito!