2016-09-30 6 views
0

Ich versuche, eine Aufgabe in Excel zu automatisieren, das Öffnen einer Webseite erfordert, zu einem Link auf dieser Seite navigieren und dann auf eine Schaltfläche auf der zweiten Seite klicken, um zu downloaden eine .xlsx-Datei.VBA Internet Explorer-Anwendung gibt unterschiedliche Ergebnisse für jeden Funktionsaufruf

Ich habe ein Skript geschrieben, das dies tun soll. Die Antwort, die ich von der Webseite bekomme, ist jedoch nicht immer dieselbe. Insbesondere wird manchmal ein Download von der ersten Seite zurückgegeben und manchmal navigiert er zur zweiten Seite und lädt nichts herunter, ein- oder zweimal hat er beides getan.

Mein Gefühl ist, dass dies damit zu tun hat, wie lange InternetExplorer.application dauert, um eine Anfrage zu vervollständigen. Ich kann jedoch nicht herausfinden, wie ich das Problem beheben kann, da ich dem Skript befehle, auf IE.application zu warten, um seine Anfrage abzuschließen.

Sub DoBrowse2() 

    'For Each lnk In Sheets("Sheet4").Hyperlinks 
     'Range(lnk).Hy.Follow 
     'Next 

    Dim i As Long 
    Dim URL As String 
    Dim BaseURL As String 
    Dim ToURL As String 
    Dim IE As Object 
    Dim objElement As Object 
    Dim objCollection As Object 
    Dim HWNDSrc As Long 
    Dim html As IHTMLDocument 

    Set IE = CreateObject("InternetExplorer.Application") 

    URL = Range("B2").Hyperlinks(1).Address 

    IE.Navigate URL 

    IE.Visible = True 

    Application.StatusBar = URL & " is loading. Please wait..." 

    Do While IE.ReadyState = 4: DoEvents: Loop 
    Do Until IE.ReadyState = 4: DoEvents: Loop 

    Application.StatusBar = URL & " Loaded" 

    'Set html = IE.Document 
    'Dim elements As IHTMLElementCollection 
    'Set elements = html.all 

    For Each itm In IE.Document.all 
     If itm.className = "datagrid" Then 
      For Each el In itm.Document.all 
       Debug.Print "hello" 
       If el.className = "ujump" And Right(el.innerText, 12) = "Constituents" Then 
        'Debug.Print el.innerText 
        ToURL = el.getAttribute("data-subset") 
        BaseURL = "http://datastream.thomsonreuters.com/navigator/search.aspx?dsid=ZUCH002&AppGroup=DSAddin&host=Metadata&prev=scmTELCMBR&s=D&subset=" 
        ToURL = BaseURL & ToURL 
        'Debug.Print ToURL 

        IE.Navigate ToURL 
        IE.Visible = True 

        Do While IE.Busy 
         Debug.Print "in busy loop" 
         Application.Wait DateAdd("s", 1, Now) 
        Loop 

        GoTo end_of_for 
       End If 
      Next 
     End If 
    Next 

end_of_for: 

    Debug.Print ("STOP STOP STOP STOP STOP") 

    Dim Script As String 

    For Each itm In IE.Document.all 
     If itm.className = "lgc excel" Then 
      Debug.Print "hello world" 
      Debug.Print itm.getAttribute("onclick") 
      itm.Click 

      Do While IE.Busy 
       Debug.Print "app busy" 
       Application.Wait DateAdd("s", 1, Now) 
      Loop 

      Exit For 

     End If 
    Next 

End Sub 

Vielen Dank im Voraus für Ihre Hilfe.

+0

Warum die Anforderung von der zweiten Seite mit Browser nicht zu prüfen, Entwickler-Tools, und machen Sie das gleiche XHR, um den Inhalt zu laden und in der Datei zu speichern? – omegastripes

+0

Danke für Ihre Antwort. Ich bin nicht sehr vertraut mit Web Scraping - oder VBA für diese Angelegenheit. Könnten Sie ein bisschen expliziter sein? – wmcass

+0

[Hier ist das Beispiel] (http://stackoverflow.com/a/32429348/2165759) zeigt, wie Sie eine Datei über XHR herunterladen, könnten Sie bitte die erste Seite URL für ein konkreteres Beispiel angeben? – omegastripes

Antwort

0

verwenden, um zu bestimmen, ob IE Seite vollständig geladen ist, es muss immer beide dieser Bedingungen:

Do Until ie.ReadyState = 4 And ie.Busy = False 
    DoEvents 
Loop 

Auch mit dem Code oben, wenn es Skripts auf der Seite sind, können einige Inhalte nach geladen werden ie.ReadyState = 4 And ie.Busy = False Zustand ist erfüllt und entweder einfach, aber ineffizient und unzuverlässig Application.Wait kann verwendet werden oder Sie können versuchen, Elemente auf der Website zu finden, die über Ladezustand informieren und den Status anhand ihrer sichtbaren Attribute usw. bestimmen.

Teil Ihres Codes ist falsch und verursacht eine Endlosschleife:

Er löst DoEvents aus, während der Bereitschaftszustand abgeschlossen ist und bis zum vollständigen Status.

Verfeinern Sie eine Sammlung aller Elemente:

For Each itm In IE.Document.all 

zu einer bestimmten Sammlung für eine bessere Leistung, wenn möglich, zum Beispiel:

For Each itm In IE.Document.GetElementsByTagName("div") 
+0

Die Lösung ist möglicherweise für einige Fälle nicht zuverlässig genug und sollte wie folgt erweitert werden (http://stackoverflow.com/a/23232573/2165759) – omegastripes

Verwandte Themen