J'essaie de récupérer des données du site Web: http://uk.investing.com/rates-bonds/financial-futures via vba, comme le prix en temps réel, c'est-à-dire l'allemand 5 YR Bobl, US 30Y T-Bond, j'ai essayé la requête Web Excel, mais il ne fait qu'effleurer tout le site Web, mais je voudrais ne gratter que le taux. Existe-t-il un moyen de le faire?
Il y a plusieurs façons de le faire. C’est une réponse que j’écris en espérant que toutes les bases de l’automatisation d’Internet Explorer seront trouvées lors de la recherche des mots-clés "extraire les données du site Web", mais rappelez-vous que rien ne vaut votre propre recherche codes pré-écrits que vous ne pouvez pas personnaliser).
Notez que ceci est un moyen , que je ne préfère pas en termes de performances (car cela dépend de la vitesse du navigateur), mais il est bon de comprendre la logique qui sous-tend l’automatisation Internet.
1) Si j'ai besoin de naviguer sur le Web, j'ai besoin d'un navigateur! Je crée donc un navigateur Internet Explorer:
Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")
2) Je demande au navigateur de parcourir la page Web cible. En utilisant la propriété ".Visible", je décide si je veux voir le navigateur faire son travail ou non. Lorsque vous créez le code, il est agréable d’avoir Visible = True
, mais lorsque le code fonctionne pour extraire des données, il est agréable de ne pas le voir à chaque fois, donc Visible = False
.
With appIE
.Navigate "http://uk.investing.com/rates-bonds/financial-futures"
.Visible = True
End With
3) La page Web aura besoin de temps pour charger. Donc, je vais attendre en attendant, il est occupé ...
Do While appIE.Busy
DoEvents
Loop
4) Eh bien, maintenant la page est chargée. Supposons que je veuille gratter le changement de l'US30Y T-Bond: Je vais simplement cliquer sur F12 sur Internet Explorer pour voir le code de la page Web, et donc utiliser le pointeur (en cercle rouge) pour cliquer sur l'élément que je veux gratter pour voir comment puis-je atteindre mon objectif.
5) Ce que je devrais faire est simple. Tout d'abord, j'obtiendrai par la propriété ID l'élément tr
qui contient la valeur:
Set allRowOfData = appIE.document.getElementById("pair_8907")
Ici, je vais obtenir une collection d'éléments td
(plus précisément, tr
est une rangée de données et les td
sont ses cellules. Nous cherchons le huitième, je vais donc écrire:
Dim myValue As String: myValue = allRowOfData.Cells(7).innerHTML
Pourquoi ai-je écrit 7 au lieu de 8? Comme les collections de cellules commencent à 0, l'indice du 8ème élément est 7 (8-1). Analyser brièvement cette ligne de code:
.Cells()
me fait accéder aux éléments td
;innerHTML
est la propriété de la cellule contenant la valeur que nous recherchons. Une fois que nous avons notre valeur, qui est maintenant stockée dans la variable myValue
, nous pouvons simplement fermer le navigateur IE et libérer la mémoire en le définissant sur Nothing:
appIE.Quit
Set appIE = Nothing
Eh bien, maintenant vous avez votre valeur et vous pouvez en faire ce que vous voulez: mettez-la dans une cellule (Range("A1").Value = myValue
) ou dans une étiquette d'un formulaire (Me.label1.Text = myValue
).
Je voudrais juste vous faire remarquer que ce n'est pas ainsi que StackOverflow fonctionne: vous posez ici des questions sur des problèmes de codage spécifiques, mais vous devez d'abord effectuer votre propre recherche. La raison pour laquelle je réponds à une question qui ne montre pas trop d’efforts de recherche, c’est simplement que je la vois poser plusieurs fois et, au moment où j’ai appris à faire cela, je me souviens que j’aurais aimé avoir une meilleure soutien pour commencer avec. J'espère donc que cette réponse, qui est juste une "entrée d'étude" et n'est pas du tout la solution la meilleure/la plus complète, peut être un support pour le prochain utilisateur ayant le même problème. Parce que j’ai appris à programmer grâce à cette communauté, et j’aime penser que vous et d’autres débutants pourriez utiliser mes contributions pour découvrir le magnifique monde de la programmation.
Profitez de votre pratique;)
D’autres méthodes ont été mentionnées, alors reconnaissons qu’au moment de la rédaction de ce document, nous sommes au XXIe siècle. Garons le bus local ouverture du navigateur et fly avec un XMLHTTP GET request (XHR GET en abrégé).
XHR est une API sous la forme d'un objet dont les méthodes transfèrent des données entre un navigateur Web et un serveur Web. L'objet est fourni par le Environnement JavaScript du navigateur
C'est une méthode rapide pour récupérer des données qui ne nécessitent pas l'ouverture d'un navigateur. La réponse du serveur peut être lue dans un document HTML et le processus de récupération de la table se poursuit à partir de là.
Dans le code ci-dessous, la table est saisie par son identifiant cr1
.
Dans le sous-assistant, WriteTable
, nous bouclons les colonnes (balises td
), puis les lignes du tableau (balises tr
), et finalement, nous parcourons la longueur de chaque ligne de tableau, cellule par cellule. Comme nous ne voulons que des données des colonnes 1 et 8, une instruction Select Case
spécifie ce qui est écrit sur la feuille.
Exemple d'affichage de page Web:
Exemple de sortie de code:
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
vous pouvez utiliser l'objet winhttprequest au lieu d'Internet Explorer, car il est conseillé de charger des données à l'exclusion des images n publicité au lieu de télécharger une page Web complète, y compris des images de publicité qui rendent les objets Internet Explorer lourds par rapport à l'objet winhttpRequest.
J'ai modifié quelque chose qui me causait des erreurs et je me suis retrouvé avec cela qui fonctionnait très bien pour extraire les données selon mes besoins
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
Cette question a été posée bien avant. Mais je pensais que les informations suivantes seraient utiles aux débutants. En fait, vous pouvez facilement obtenir les valeurs du nom de la classe comme ceci.
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
Et si vous débutez dans le Web, lisez ce billet.
De plus, il existe différentes techniques pour extraire des données de pages Web. Cet article explique quelques-uns d'entre eux avec des exemples.