Web scraping avec vba en utilisant XMLHTTP


2

Je voudrais obtenir quelques données de la page Web http://www.eex.com/en/market-data/power/derivatives-market/phelix-futures.

Si j'utilise l'ancien objet InternetExplorer (code ci-dessous), je pourrais parcourir un document HTML. Mais je voudrais utiliser XMLHTTP objet (deuxième code).

Sub IEZagon() 
    'we define the essential variables 
    Dim ie As Object 
    Dim TDelement, TDelements 
    Dim AnhorLink, AnhorLinks 

    'add the "Microsoft Internet Controls" reference in your VBA Project indirectly 
    Set ie = CreateObject("InternetExplorer.Application") 
    With ie 
     .Visible = True 
     .navigate ("[URL]http://www.eex.com/en/market-data/power/derivatives-market/phelix-futures[/URL]") 
     While ie.ReadyState <> 4 
      DoEvents 
     Wend 
     Set AnhorLinks = .document.getElementsbytagname("a") 
     Set TDelements = .document.getElementsbytagname("td") 
     For Each AnhorLink In AnhorLinks 
      Debug.Print AnhorLink.innertext 
     Next 
     For Each TDelement In TDelements 
      Debug.Print TDelement.innertext 
     Next 
    End With 
    Set ie = Nothing 
End Sub 

Code Utilisation avec objet XMLHTTP:

Sub FuturesScrap(ByVal URL As String) 
    Dim XMLHttpRequest As XMLHTTP 
    Dim HTMLDoc As New HTMLDocument 

    Set XMLHttpRequest = New MSXML2.XMLHTTP 
    XMLHttpRequest.Open "GET", URL, False 
    XMLHttpRequest.send 
    While XMLHttpRequest.readyState <> 4 
     DoEvents 
    Wend 

    Debug.Print XMLHttpRequest.responseText 
    HTMLDoc.body.innerHTML = XMLHttpRequest.responseText 

    With HTMLDoc.body 
     Set AnchorLinks = .getElementsByTagName("a") 
     Set TDelements = .getElementsByTagName("td") 

     For Each AnchorLink In AnchorLinks 
      Debug.Print AnhorLink.innerText 
     Next 

     For Each TDelement In TDelements 
      Debug.Print TDelement.innerText 
     Next 
    End With 
End Sub 

Je reçois seulement HTML de base:

<html> 
<head> 
<title>Resource Not found</title> 
<link rel= 'stylesheet' type='text/css' href='/blueprint/css/errorpage.css'/> 
</head> 
<body> 
<table class="header"> 
<tr> 
<td class="CMTitle CMHFill"><span class="large">Resource Not found</span></td> 
</tr> 
</table> 
<div class="body"> 
<p style="font-weight:bold;">The requested resource does Not exist.</p> 
</div> 
<table class="footer"> 
<tr> 
<td class="CMHFill"> </td> 
</tr> 
</table> 
</body> 
</html> 

Je voudrais marcher dans les tables et les données ... Et lui correspondant enfin je souhaite sélectionner un intervalle de temps différent d'une année à l'autre:

I J'apprécie vraiment toute aide! Je vous remercie!

+2

On dirait que vous demandez une URL incorrecte ... 08 févr.. 142014-02-08 00:52:06

  0

Je suis Colling URL droite: 08 févr.. 142014-02-08 08:09:01

  0

Voir la réponse de @ brettdj [ICI] (http://stackoverflow.com/questions/8798260/html- parsing-of-cricinfo-scorecards) 08 févr.. 142014-02-08 08:48:27

  0

J'ai lu cet article hier mais je n'ai pas trouvé de réponse à propos de la page de grattage avec l'objet XMLHTTP. Www je colling utilise javascript pour afficher toutes les données financières, de sorte que le problème est autour de readystate et à droite en utilisant l'objet XMLHTTP. Je n'ai pas de problème en utilisant l'ancien InternetExplorer. Mais c'est lent et inconfortable ... 08 févr.. 142014-02-08 10:01:19

3

Je peux confirmer que je reçois le même code HTML que vous lorsque je lance votre code (avec ou sans les balises url). J'ai trouvé un message utile here. J'ai modifié votre code en utilisant la méthode trouvée ici et il semble maintenant avoir téléchargé les informations correctes. J'ai inclus le sous appelant parce que les balises d'URL semblaient provoquer une erreur pour la demande MSXML.

Sub FuturesScrap1(ByVal URL As String) 
    Dim HTMLDoc As New HTMLDocument 
    Dim oHttp As MSXML2.XMLHTTP 
    Dim sHTML As String 
    Dim AnchorLinks As Object 
    Dim TDelements As Object 
    Dim TDelement As Object 
    Dim AnchorLink As Object 

    On Error Resume Next 
    Set oHttp = New MSXML2.XMLHTTP 
    If Err.Number <> 0 Then 
     Set oHttp = CreateObject("MSXML.XMLHTTPRequest") 
     MsgBox "Error 0 has occured while creating a MSXML.XMLHTTPRequest object" 
    End If 
    On Error GoTo 0 
    If oHttp Is Nothing Then 
     MsgBox "For some reason I wasn't able to make a MSXML2.XMLHTTP object" 
     Exit Sub 
    End If 

    'Open the URL in browser object 
    oHttp.Open "GET", URL, False 
    oHttp.send 
    sHTML = oHttp.responseText 

    Debug.Print oHttp.responseText 

    HTMLDoc.body.innerHTML = oHttp.responseText 

    With HTMLDoc.body 
     Set AnchorLinks = .getElementsByTagName("a") 
     Set TDelements = .getElementsByTagName("td") 

     For Each AnchorLink In AnchorLinks 
      Debug.Print AnchorLink.innerText 
     Next 

     For Each TDelement In TDelements 
      Debug.Print TDelement.innerText 
     Next 
    End With 

End Sub 

Modifier folowing commentaire:

Je n'ai pas été en mesure de trouver les éléments de table en utilisant l'objet MSXML2, le code source ne semble pas les contenir. Dans firebug les tags td sont présents donc je pense que la table est générée par le code JavaScript. Je ne sais pas si MSXML2 peut exécuter le JavaScript alors j'ai modifié le sous-navigateur pour utiliser Internet Explorer, ce n'est pas du code rapide, mais il trouve les éléments td et permet de cliquer sur les onglets. J'ai trouvé que les éléments td peuvent prendre un certain temps à devenir disponibles (probablement pour IE doit exécuter le JavaScript) donc j'ai mis en quelques étapes où xl attend avant de télécharger les données.

J'ai mis du code qui téléchargera le contenu des éléments td dans la feuille de calcul active, faites attention si vous l'exécutez dans un classeur contenant des données utiles.

Sub FuturesScrap3(ByVal URL As String) 

    Dim HTMLDoc As New HTMLDocument 
    Dim AnchorLinks As Object 
    Dim tdElements As Object 
    Dim tdElement As Object 
    Dim AnchorLink As Object 
    Dim lRow As Long 
    Dim oElement As Object 

    Dim oIE As InternetExplorer 

    Set oIE = New InternetExplorer 

    oIE.navigate URL 
    oIE.Visible = True 

    Do Until (oIE.readyState = 4 And Not oIE.Busy) 
     DoEvents 
    Loop 

    'Wait for Javascript to run 
    Application.Wait (Now + TimeValue("0:01:00")) 

    HTMLDoc.body.innerHTML = oIE.document.body.innerHTML 

    With HTMLDoc.body 
     Set AnchorLinks = .getElementsByTagName("a") 
     Set tdElements = .getElementsByTagName("td") ' 

     For Each AnchorLink In AnchorLinks 
      Debug.Print AnchorLink.innerText 
     Next AnchorLink 

    End With 

    lRow = 1 
    For Each tdElement In tdElements 
     Debug.Print tdElement.innerText 
     Cells(lRow, 1).Value = tdElement.innerText 
     lRow = lRow + 1 
    Next 

    'Clicking the Month tab 
    For Each oElement In oIE.document.all 
     If Trim(oElement.innerText) = "Month" Then 
      oElement.Focus 
      oElement.Click 
     End If 
    Next oElement 

    Do Until (oIE.readyState = 4 And Not oIE.Busy) 
     DoEvents 
    Loop 

    'Wait for Javascript to run 
    Application.Wait (Now + TimeValue("0:01:00")) 

    HTMLDoc.body.innerHTML = oIE.document.body.innerHTML 

    With HTMLDoc.body 
     Set AnchorLinks = .getElementsByTagName("a") 
     Set tdElements = .getElementsByTagName("td") ' 

     For Each AnchorLink In AnchorLinks 
      Debug.Print AnchorLink.innerText 
     Next AnchorLink 
    End With 

    lRow = 1 
    For Each tdElement In tdElements 
     Debug.Print tdElement.innerText 
     Cells(lRow, 2).Value = tdElement.innerText 
     lRow = lRow + 1 
    Next tdElement 

End sub 
  0

J'ai fait le même code samedi dernier. Mais j'ai encore des problèmes sur cette page web. Avec votre code et moi, je ne peux pas lister 6 boutons (ancres) avec le nom Année du jour. Si je veux marcher à travers les différentes tables en fonction de la fenêtre de temps (année, trimestre, etc), je dois cliquer sur l'un de ces boutons. Mais ce n'est pas le dernier problème, dans notre code, nous ne pouvons pas lister les données des tables avec du code: [code] Pour chaque TDelement Dans TDelements Debug.Print TDelement.innerText Suivant [\ code] 12 févr.. 142014-02-12 15:17:33

+1

@Figlio J'ai modifié la réponse pour obtenir les éléments TD et pour permettre de changer la table, elle utilise cependant l'explorateur interenet, plutôt que MSXML2, cela peut être nécessaire en raison de JavaScript. 12 févr.. 142014-02-12 23:38:13

  0

Merci. Avec l'objet IE fonctionne. Je sais, j'ai fait le même code que vous avez fait. Et j'ai le même problème qui nécessite Application.wait metod. Si c'est le cas et ne pas aller avec XMLHTTP, je vais rester sur IE. Merci encore! 13 févr.. 142014-02-13 09:03:45