Este post foi originalmente publicado em http://officevbavsto.blogspot.com/2011/03/vba-internet-acessando-sites-da-web.html
Nesta quarta parte, eu abordo os seguintes assuntos: clicando em links, lendo dados de tabelas e interagindo com frames.
Links
Utilizaremos, como exemplo, o código fonte HTML a seguir:
<a href="http://www.yahoo.com/">Click Here</a>Utilize o objeto Links que está contido no objeto Document:
Sub AcessaPagina()
Dim ie As InternetExplorer
Set ie = New InternetExplorer
ie.Navigate "http://users5.nofeehost.com/BackOfficeSite/Vba_Site_Iv_Links.htm"
ie.Visible = True
ie.Document.Links(0).Click
End SubA propriedade Links retorna uma coleção de todos os elementos “AREA” e elementos ancora (<a href="...">) com valor na propriedade href [1].
Utilize a propriedade Length para verificar existem links no site. Assim você evita erros em tempo de execução:
Sub AcessaPagina()
Dim ie As InternetExplorer
Set ie = New InternetExplorer
ie.Navigate "http://users5.nofeehost.com/BackOfficeSite/Vba_Site_Iv_Links.htm"
ie.Visible = True
If ie.Document.Links.Length > 0 Then
ie.Document.Links(0).Click
End If
End SubE se a página que estou acessando tiver milhares de links? Utilize uma estrutura de repetição itere cada Link:
Sub AcessaPagina()
Dim ie As InternetExplorer
Set ie = New InternetExplorer
ie.Navigate "http://users5.nofeehost.com/BackOfficeSite/Vba_Site_Iv_Links.htm"
ie.Visible = True
Dim obj As Object
For Each obj In ie.Document.Links
If obj.href = "http://www.yahoo.com/" Then
obj.Click
End If
Next obj
End SubNa segunda parte deste artigo, eu mencionei sobre o uso da Janela de Variáveis Locais (Local Variables Window).
A Janela de Variáveis Locais mostra o valor de todas as variáveis locais. Uma variável local é uma variável definida dentro de um procedimento (Sub ou Function) e, portanto, não é válida dentro de outro procedimento (Sub ou Function) [2].
Torno a repetir chamando a atenção para a variável "obj" do exemplo acima. Veja quantas propriedades e quantas informações nós podemos extrair. É possível vermos a porta que é utilizada para acesso (80), o protocolo (HTTP), o texto contido dentro das tags do link ("Click Here"), entre outros.
Dim varProtocolo as String
varProtocolo = ie.document.links(0).protocolA propriedade protocol do objeto links especifica o protocolo sendo usado no navegador [3].
Tabelas
Tabelas são definidas através da tag <table>. Uma tabela é dividida em linhas (através da tag <tr> - Table Row), e cada coluna é dividida em células (através da tag <td> - Table Data Cell) [7]. Entre as tags <td> é onde inserimos o conteúdo de cada célula da tabela.
O código-fonte HTML de uma tabela é o seguinte:
<table>
<tr>
<td>Conteúdo de célula 1 da linha 1</td>
<td>Conteúdo de célula 2 da linha 1</td>
<td>Conteúdo de célula 3 da linha 1</td>
</tr>
<tr>
<td>Conteúdo de célula 1 da linha 2</td>
<td>Conteúdo de célula 2 da linha 2</td>
<td>Conteúdo de célula 3 da linha 2</td>
</tr>
</table> Vamos a um primeiro exemplo de código:
Sub AcessaPagina()
Dim ie As InternetExplorer
Set ie = New InternetExplorer
ie.Navigate "http://users5.nofeehost.com/BackOfficeSite/Vba_Site_Iv_Tables.htm"
ie.Visible = True
MsgBox ie.Document.all.Item(6).Rows(0).Cells(0).innerText
End SubItem(6): na coleção de itens em meu site, o item 6 (que é o sétimo item dado que a contagem começa a partir de 0) corresponde à uma tabela (em HTML,<table></table>)Rows(0): primeira linha de minha tabela (em HTML<tr></tr>);Cells(0): primeira célula de minha tabela (em HTML<td></td>);innerText: retorna o texto dentro da célula.
Acessamos a tabela pelo seu índice - Item(6). E se o site tiver mais de 1000 itens, como fazer para saber qual índice corresponde à tabela que quero acessar? Terei que sair caçando na Janela de Variáveis Locais seu índice correspondente? Não! Existe uma maneira de referenciar a tabela sem precisar saber qual seu índice na coleção de Items do objeto Document.
Sub AcessaPagina()
Dim ie As InternetExplorer
Set ie = New InternetExplorer
ie.Navigate "http://users5.nofeehost.com/BackOfficeSite/Vba_Site_Iv_Tables.htm"
ie.Visible = True
Dim elemCollection As Object
Dim obj As Object
Set elemCollection = ie.Document.getElementsByTagName("TABLE")
For Each obj In elemCollection
MsgBox obj.Rows(0).Cells(0).innerText
Next obj
End SubUtilizamos o método getElementsByTagName() para retornar a coleção de objetos correspondentes aquela tag especifica, ou seja, se tivéssemos mais de uma tabela em nossa página, esse método retornaria todas atribuindo-as à variável elemCollection. Então, através da variável obj, iteramos (loop) por todas as tabelas retornadas na variável elemColletion. E com a variável obj, acessamos as linhas (rows) e células (cells) da tabela.
O método getElementsByTagName acessa todos os elementos com o nome da tag especificada [4].
Esse método também serve para todas outras tags, tais como "a", "tr", "td" e etc.
E para finalizar o assunto de tabelas, segue algoritmo que lê os dados da tabela na página da internet e os copia para a planilha:
Sub AcessaPagina()
Dim ie As InternetExplorer
Set ie = New InternetExplorer
ie.Navigate "http://users5.nofeehost.com/BackOfficeSite/Vba_Site_Iv_Tables.htm"
ie.Visible = True
Dim elemCollection As Object
Dim t As Integer
Dim r As Integer, c As Integer
Set elemCollection = ie.Document.getElementsByTagName("TABLE")
For t = 0 To elemCollection.Length - 1
For r = 0 To elemCollection(t).Rows.Length - 1
For c = 0 To elemCollection(t).Rows(r).Cells.Length - 1
ThisWorkbook.Worksheets(1).Cells(r + 1, c + 1) = _
elemCollection(t).Rows(r).Cells(c).innerText
Next c
Next r
Next t
End SubFrames
Bem, lidar com Frames é extremamente simples. Basta você saber o nome (propriedade "name" na tag html) do frame onde você quer acessar o conteúdo.
Um objeto Frame representa um frame HTML. A tag <frame> define uma janela particular (frame) dentro de um Frameset (conjunto de frames). Para cada tag <frame> em um documento HTML, um objeto Frame é criado [5].
A tag <frameset> é um elemento HTML que é usado para conter elementos <frame> [6].
O código fonte de um frame é o seguinte:
<frameset cols="25%,75%">
<frame src="http://users5.nofeehost.com/BackOfficeSite/Frame_A.html" name="Frame_A">
</frame>
<frame src="http://users5.nofeehost.com/BackOfficeSite/Vba_Site_Iv_Tables.htm" name="Frame_B">
</frame>
</frameset>Vamos ao código VBA:
Sub AcessaPagina()
Dim ie As InternetExplorer
Set ie = New InternetExplorer
ie.Navigate "http://users5.nofeehost.com/BackOfficeSite/Vba_Site_Iv_Frames.htm"
ie.Visible = True
MsgBox ie.Document.frames("Frame_A").Document.all.Item(0).innertext
End Subframes(nome_do_frame ou numero_do_item): acessa determinado frame de acordo com o nome especificado ou com o número correspondente (frames(0), por exemplo).
Créditos
Photo by Markus Spiske from Pexels
Referência Bibliográfica:
- document.links: https://developer.mozilla.org/en-US/docs/DOM/document.links, acessado em 10.03.2013;
- Roman, Steven. Writing Excel Macros with VBA, 2nd Edition. Sebastopol, California (USA). O’Reilly Media Inc. 2002;
- JavaScript Link Object : protocol Property: http://www.w3resource.com/javascript/client-object-property-method/link-protocol.php, acessado em 10.03.2013;
- Document getElementsByTagName() Method: http://www.w3schools.com/jsref/met_doc_getelementsbytagname.asp, acessado em 10.03.2013;
- HTML DOM Frame and IFrame Objects: http://www.w3schools.com/jsref/dom_obj_frame.asp, acessado em 10.03.2013;