Raspagem de dados do sítio web que utiliza o vba
estou a tentar retirar dados do sítio Web: http://uk.investing.com/rates-bonds/financial-futures via vba, como o preço em tempo real, ou seja, alemão 5 YR Bobl, US 30Y T-Bond, eu tentei consulta excel web, mas só raspa todo o site, mas eu gostaria de raspar apenas a taxa, existe uma maneira de fazer isso?
5 answers
Por favor, note que este é um caminho, que eu não Prefiro em termos de desempenho (uma vez que depende do navegador speed) mas isso é bom para entender a lógica por trás da automação da Internet.
1) Se eu precisar de navegar na web, eu preciso de um navegador! Então eu crio um navegador Internet Explorer:
Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")
2) peço ao navegador para navegar na página de destino. Através do uso da propriedade ".Visível", eu decido se quero ver o navegador fazendo o seu trabalho ou não. Ao construir o código é bom ter Visible = True
, mas quando o código está trabalhando para raspar dados é bom não vê-lo todas as vezes assim Visible = False
.
With appIE
.Navigate "http://uk.investing.com/rates-bonds/financial-futures"
.Visible = True
End With
3) a página web vai precisar de algum tempo para carregar. Por isso, vou esperar que esteja ocupado...
Do While appIE.Busy
DoEvents
Loop
Bem, agora a página está carregada. Vamos dizer que eu quero raspar a mudança da US30Y T-Bond:
O que eu vou fazer é clicar em F12 no Internet Explorer para ver o código da página web, e, portanto, usando o ponteiro (em círculo vermelho) eu vou clicar no elemento que eu quero raspar para ver como posso alcançar o meu propósito.
O que devo fazer é ... simples. Em primeiro lugar, Vou obter pela propriedade ID o elemento tr
que contém o valor:
Set allRowOfData = appIE.document.getElementById("pair_8907")
Aqui eu vou obter uma coleção de td
elementos (especificamente, tr
é uma linha de dados, e o td
são suas células. Estamos à procura do dia 8, por isso vou escrever:
Dim myValue As String: myValue = allRowOfData.Cells(7).innerHTML
Porque escrevi 7 em vez de 8? Como as coleções de células começam a partir de 0, então o índice do 8º elemento é 7 (8-1). Em breve, analisaremos esta linha de Código:
-
.Cells()
Faz-me aceder aos elementostd
; -
innerHTML
é propriedade da célula que contém o valor que procuramos.
Uma vez que tenhamos o nosso valor, que agora está armazenado na variável myValue
, podemos apenas fechar o navegador IE e liberar a memória, configurando-o para nada:
appIE.Quit
Set appIE = Nothing
Bem, agora você tem o seu valor e pode fazer o que quiser com ele: colocá-lo em uma célula (Range("A1").Value = myValue
), ou em um rótulo de uma forma (Me.label1.Text = myValue
).
Eu só gostaria de salientar que não é assim que o StackOverflow funciona: aqui você coloca perguntas sobre problemas específicos de codificação, mas você deve fazer sua própria pesquisa primeiro. A razão pela qual eu estou respondendo a uma pergunta que não está mostrando muito esforço de pesquisa é apenas que eu vejo isso feito várias vezes e, de volta ao tempo em que eu aprendi a fazer isso, eu me lembro que eu teria gostado de ter algum apoio melhor para começar. Espero, pois, que esta resposta, que é apenas uma "entrada de estudo" e não a solução melhor/mais completa, pode ser um suporte para o próximo usuário ter o mesmo problema. Porque eu aprendi como programar graças a esta comunidade, e eu gosto de pensar que você e outros iniciantes podem usar minha entrada para descobrir o belo mundo da programação.
Desfrutem da vossa prática.É um método rápido para recuperar dados que não requerem a abertura de um navegador. A resposta do servidor pode ser lida em um HTMLDocument e o processo de pegar a tabela continuou a partir daí.XHR é uma API na forma de um objecto cujos métodos transferem dados entre um navegador web e um servidor web. O objecto é fornecido pela JavaScript do navegador ambiente
No código abaixo, a tabela é agarrada pelo seu id cr1
.
No sub auxiliar, WriteTable
, fazemos um loop nas colunas (td
} e depois nas linhas da tabela (tr
}), e finalmente atravessamos o comprimento de cada linha da tabela, célula da tabela por celula. Como só queremos dados das colunas 1 e 8, é usada uma declaração Select Case
especifique o que está escrito na folha.
Mostrar a vista da página web:
Saída do Código Da Amostra:
VBA:
Option Explicit
Public Sub GetRates()
Dim sResponse As String, html As New HTMLDocument '<== Tools > References > HTML Object Library
Dim hTable As HTMLTable
Application.ScreenUpdating = False
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://uk.investing.com/rates-bonds/financial-futures", False
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
.send
sResponse = StrConv(.responseBody, vbUnicode)
End With
sResponse = Mid$(sResponse, InStr(1, sResponse, "<!DOCTYPE "))
With html
.body.innerHTML = sResponse
Set hTable = .getElementById("cr1")
WriteTable hTable, 1, ThisWorkbook.Worksheets("Sheet1")
End With
Application.ScreenUpdating = True
End Sub
Public Sub WriteTable(ByVal hTable As HTMLTable, Optional ByVal startRow As Long = 1, Optional ByVal ws As Worksheet)
Dim tSection As Object, tRow As Object, tCell As Object, tr As Object, td As Object, r As Long, C As Long, tBody As Object
r = startRow: If ws Is Nothing Then Set ws = ActiveSheet
With ws
Dim headers As Object, header As Object, columnCounter As Long
Set headers = hTable.getElementsByTagName("th")
For Each header In headers
columnCounter = columnCounter + 1
Select Case columnCounter
Case 2
.Cells(startRow, 1) = header.innerText
Case 8
.Cells(startRow, 2) = header.innerText
End Select
Next header
startRow = startRow + 1
Set tBody = hTable.getElementsByTagName("tbody")
For Each tSection In tBody
Set tRow = tSection.getElementsByTagName("tr")
For Each tr In tRow
r = r + 1
Set tCell = tr.getElementsByTagName("td")
C = 1
For Each td In tCell
Select Case C
Case 2
.Cells(r, 1).Value = td.innerText
Case 8
.Cells(r, 2).Value = td.innerText
End Select
C = C + 1
Next td
Next tr
Next tSection
End With
End Sub
Você pode usar o objecto winhttprequest em vez do internet explorer, pois é bom carregar dados excluindo Imagens n anúncio em vez de descarregar a página web completa, incluindo imagens de anúncio n que tornam o objecto do internet explorer pesado em comparação com o objecto do winhttpRequest.
Sub ExtractLastValue()
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Top = 0
objIE.Left = 0
objIE.Width = 800
objIE.Height = 600
objIE.Visible = True
objIE.Navigate ("https://uk.investing.com/rates-bonds/financial-futures/")
Do
DoEvents
Loop Until objIE.readystate = 4
MsgBox objIE.document.getElementsByClassName("pid-8907-last")(0).innerText
End Sub
E se você é novo para raspar web por favor leia este post no blog.
Raspagem Da Web-Noções Básicas
E também existem várias técnicas para extrair dados de páginas web. Este artigo explica alguns deles com exemplos.
Sub get_data_web()
Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")
With appIE
.navigate "https://finance.yahoo.com/quote/NQ%3DF/futures?p=NQ%3DF"
.Visible = True
End With
Do While appIE.Busy
DoEvents
Loop
Set allRowofData = appIE.document.getElementsByClassName("Ta(end) BdT Bdc($c-fuji-grey-c) H(36px)")
Dim i As Long
Dim myValue As String
Count = 1
For Each itm In allRowofData
For i = 0 To 4
myValue = itm.Cells(i).innerText
ActiveSheet.Cells(Count, i + 1).Value = myValue
Next
Count = Count + 1
Next
appIE.Quit
Set appIE = Nothing
End Sub