Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1556to1560
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Per VBA Daten von Website abgreifen
05.05.2017 07:58:01
Website
Hallo liebe Forumsmitglieder,
ich versuche mich vermehrt in die Steuerung / Auslesung von Daten aus dem Internet Explorer mithilfe von VBA einzuarbeiten.
Dabei habe ich bislang folgenden Code erstellt, welcher auf Google.de navigieren, dann ein Suchbegriff hinterlegen(der in Zelle "B4" steht) und die Anzahl der Suchtreffer ausgeben soll (in Zelle "A1").
Leider bekomme ich bei der Ausführung hin und wieder (nicht immer) den Laufzeitfehler 13 "Typen unverträglich". Das Problem scheint an der variable "searchres" zu liegen, welche ich als Variant deklariert habe.
hier Code:
Option Explicit
Sub ietest()
Dim ie As Object
Dim searchtxt As Object
Dim searchres As Variant
Set ie = CreateObject("internetexplorer.application")
With ie
.Visible = True
.navigate "https://www.google.de"
Do While .Busy
DoEvents
Loop
Do While .readyState  4
DoEvents
Loop
Set searchtxt = .document.getElementById("lst-ib")
searchtxt.Value = ThisWorkbook.Sheets(1).Range("B4")
.document.forms(0).submit
Do While .Busy
DoEvents
Loop
Do While .readyState  4
DoEvents
Loop
Set searchres = .document.getElementById("resultStats")

ThisWorkbook.Sheets(1).Range("A1") = searchres.innerText
.Quit
End With
End Sub
Kann mir jemand bitte helfen?
Vielen Dank im Voraus.
Viele Grüße
Marco

12
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Per VBA Daten von Website abgreifen
05.05.2017 12:48:26
Website
Hallo Marco,
ich möchte Dir zwei Anmerkungen mit auf den Weg geben
1.
Die beiden Code-Abschnitte

Do While .Busy
DoEvents
Loop

und

Do While .readyState  4
DoEvents
Loop

machen exakt das gleiche. Du brauchst nur einen davon. Beim ersten sagst Du dem Browser, er soll so lange warten, wie er beschäftigt ist. Mit dem zweiten gibst Du durch den Wert 4 direkt an, dass der Browser so lange warten soll, bis das Dokument vollständig geladen ist. Nachdem der Browser diese Meldung zurück liefert, läuft das Makro weiter.
Zweimal brauchst Du so ein Konstrukt auf Seiten, die z.B. einen iFrame enthalten, in den nach dem eigentlichen Seitenaufbau noch etwas nachgeladen wird. Dann meldet der Browser nämlich nach dem Lader der Hauptseite, dass er fertig ist. Der iFrame wird dann aber nachgeladen und dadurch verfällt der Browser wieder in den Ladezustand.
Dieses Verhalten hast Du z.B. bei eBay Angeboten. Dort wird der Angebotstext immer erst geladen, wenn der Rest der Seite schon steht.
2.
Du benutzt die Seite, als sitzt ein Mensch davor, indem du das Formular befüllst und die Suchanfrage über den Submit Button abschickst. Das ist nicht notwendig. Du brauchst lediglich einen einzigen Zugriff auf den Browser, wenn Du den kompletten Suchlink direkt an ihn schickst.
Im Fall von Google wäre das für die beiden Suchwörter "Trockeneis" und "Berlin" der Link
https://www.google.de/#q=trockeneis+berlin
Hinter dem eigentlichen Seitenaufruf kannst Du also immer fest den Parameter #q= angeben und dahinter Deine Suchwörter, die einfach durch ein + getrennt werden. Dir wird dann direkt die Suchseite mit den Ergebnissen angezeigt.
Du brauchst dann auch für die Suchbegriffe kein Objekt, sondern einfach nur einen String

Sub ietest()
Dim ie As Object
Dim URL As String
Dim searchtxt As String
Dim searchres As Variant
Set ie = CreateObject("internetexplorer.application")
URL = "https://www.google.de\#q="
searchtxt = "Trockeneis+Berlin" 'An eigene Bedürfnisse anpassen
'Auch übernahme aus einer Zelle möglich
With ie
.Visible = True
.navigate URL & searchtxt
Do While .readyState  4
DoEvents
Loop
End With
'Hier Deine weiter Verarbeitung
Set ie = Nothing
End Sub
Viele Grüße,
Zwenn
Anzeige
AW: Per VBA Daten von Website abgreifen
08.05.2017 08:26:37
Website
Hallo Zwenn,
vielen Dank für die super Hilfe!
Wenn ich allerdings den Code nun weiterschreiben möchte und z.B. wie anfangs die Suchergebnisse auslesen will, bekomme ich einen Fehler bei .document (unzulässiger Verweis). Kann mir jemand sagen, was ich hier falsch gemacht habe?
Sub ietest2()
Dim ie As Object
Dim URL As String
Dim searchtxt As String
Dim searchres As String
Set ie = CreateObject("internetexplorer.application")
URL = "https://www.google.de\#q="
searchtxt = ThisWorkbook.Sheets(1).Range("B6") 'An eigene Bedürfnisse anpassen
'Auch übernahme aus einer Zelle möglich
With ie
.Visible = True
.navigate URL & searchtxt
Do While .readyState  4
DoEvents
Loop
End With
'Hier Deine weiter Verarbeitung
Set searchres = .document.getElementById("resultStats")
ThisWorkbook.Sheets(1).Range("A7") = searchres.innerText
Set ie = Nothing
End Sub
Vielen Dank im Voraus,
Beste Grüße
Marco
Anzeige
AW: Per VBA Daten von Website abgreifen
08.05.2017 15:37:06
Website
Hallo Marco,
nur ganz kurz aus dem Büro:
Du musst entweder ie vor .document.getElementById("resultStats") schreiben oder das End With unter diese Zeile setzen. Du referenzierst mit dem führenden Punkt auf ein VBA-Objekt, das dem Script in der Zeile nicht mehr bekannt ist.
Also entweder
ie.document.getElementById("resultStats")

oder

.document.getElementById("resultStats")
End With

und das End With paar Zeilen höher wegnehmen.
Noch eine Anmerkung:
Es kann sein, dass Du ausgerechnet mit der Google Seite in Probleme läufst, weil die beim Ansehen des Quelltextes eigentlich nur aus lauter JavaScript Abschnitten besteht. Die ID, die Du suchst findet man in dieser Ansicht gar nicht. Was ins Document-Objekt des VBA-Scripts übernommen wird habe ich nicht geprüft.
Aber mit der Steuerung und Abfrage von Seitenelementen über das DOM bist Du auf jeden Fall schon sehr gut dabei und auf dem richtigen Weg.
Viele Grüße,
Zwenn
Anzeige
AW: Per VBA Daten von Website abgreifen
08.05.2017 16:25:50
Website
Ich nochmal,
mir fällt grade erst auf, dass Du für die Variable searchres den Datentyp Variant verwendest. Ändere den mal auf Object, dann sollte es keine Probleme mehr geben.
AW: Per VBA Daten von Website abgreifen
09.05.2017 07:23:39
Website
Hallo Zwenn,
super, vielen Dank für die schnelle Hilfe.
Ich bin sehr dankbar für die Mühe die Du Dir da gemacht hast.
Ich habe den Code soweit angepasst, bekomme aber leider noch immer den Fehler "424 - Objekt erforderlich" mit Verweis auf searchres. Siehe Code:

Sub ietest2()
Dim ie As Object
Dim URL As String
Dim searchtxt As String
Dim searchres As Object
Set ie = CreateObject("internetexplorer.application")
URL = "https://www.google.de\#q="
searchtxt = ThisWorkbook.Sheets(1).Range("B6") 'An eigene Bedürfnisse anpassen
'Auch übernahme aus einer Zelle möglich
With ie
.Visible = True
.navigate URL & searchtxt
Do While .readyState  4
DoEvents
Loop
End With
Set searchres = ie.document.getElementById("resultStats")
ThisWorkbook.Sheets(1).Range("A7") = searchres.innerText
'Hier Deine weiter Verarbeitung
Set ie = Nothing
End Sub
Vielleicht liegt dies ja wirklich an der Google-Seite, oder hast Du sonst noch eine Idee?
Viele Grüße
Marco
Anzeige
AW: Per VBA Daten von Website abgreifen
09.05.2017 08:49:14
Website
Hallo,
bei der Codeausführung habe ich gerade bemerkt, dass nachdem der Code mit besagten Fehler stockt, wenn ich eine schrittweise Ausführung mache, der Code dann funktioniert.
Also beim Ausführen als ganzes stockt der Prozess bei searchres, dann kann ich schrittweise weitermachen und es funktioniert :/, ich versteh leider das Problem nicht.
Liebe Grüße
Marco
AW: Per VBA Daten von Website abgreifen
09.05.2017 13:13:17
Website
Hallo Marco,
immer, wenn Du aus dem Dokument des Browser-Objektes Daten übernehmen willst, musst Du prüfen, ob der gewünschte Inhalt überhaupt auf der Seite vorhanden ist.

Set searchres = ie.document.getElementById("resultStats")
If Not serchres is Nothing Then   'Prüfen, ob die Objektvariable serchres
'durch die Set-Zeile vorher einen Inhalt
'zugewiesen bekommen hat
'Wenn ja, hier den "abgetrennten" Inhalt des Dokuments weiter verarbeiten
End If

Dieser Schritt beseitigt einen Objektfehler, wie Du ihn vermutlich bekommst. Der plopt bei Dir wahrscheinlich auf, weil resultStats nicht als ID gefunden wird und deshalb kein Objekt erzeugt wird, auf das Du hinterher zugreifen kannst. Genau das ist das Verhalten, das ich (ohne es bisher geprüft zu haben), dem Aufbau der Google Seite zuschreibe. Denn die Results werden ja im Browser angezeigt.
Da ich im Büro sitze, kann ich im Moment nicht weiter darauf eingehen oder das spezifische Problem untersuchen. Ich hänge Dir aber mal ein kleines Projekt an, dass ich mal für einen anderen Foren User erstellt habe. Da geht es um das Auslesen von Ergebnissen der NBA. Der Quelltext des Makros enthält sehr viele und ausführliche Kommentare. Da solltest Du einiges für Dich rausziehen können.
https://www.herber.de/bbs/user/113442.xlsm
Viele Grüße,
Zwenn
Anzeige
AW: Per VBA Daten von Website abgreifen
09.05.2017 16:42:04
Website
Auch hallo,
beim Ausführen als ganzes stockt der Prozess bei searchres, dann kann ich schrittweise weitermachen und es funktioniert
das deutet daraufhin, dass die Seite noch nicht geladen wurde.
Schaue dir das hier an, ist auch wie bei Zwenn kommentiert.
mfg Anton
AW: Per VBA Daten von Website abgreifen
09.05.2017 20:08:41
Website
Hallo Anton,
grade habe ich mit Erstaunen gelesen, wie Du das Warten auf den Browser 3x durchführst, wobei Du über die ersten beiden schreibst, die sollen erstmal abwarten, bis der IE geladen wurde. Bist Du sicher, dass das notwendig ist?
Ich frage, weil ich schon mehrere Makros zum Auslesen von Webseiten über den IE geschrieben habe. Unter anderem eins, mit dem seit mehr als 1,5 Jahren bereits über 1,8 Mio. Angebote einer französischen Handlesplattform ausgelesen wurden. Da habe ich die "Wartezeile" aber nur ein einziges Mal drin.
Hast Du mehr Infos zu Deinen Kommentaren oder einen Link, wo ich zu diesem Vorgehen etwas nachlesen kann?
Viele Grüße,
Zwenn
Anzeige
AW: Per VBA Daten von Website abgreifen
10.05.2017 16:01:58
Website
Hallo Zwenn,
wie Du das Warten auf den Browser 3x durchführst
das 2.Warten scheint mir jetzt auch überflüssig(schleppe ich seit etwa 12 Jahren mit), aber das 3. wartet nicht auf Browser, sondern auf die Seite, ob die schon geladen wurde.Gerade an der Stelle hat Marco IMHO das Problem: Seite ist noch nicht geladen und er versucht schon auf die zuzugreifen.
Hier noch ein Link, wo man etwas zum IE nachlesen kann.
mfg Anton
AW: Per VBA Daten von Website abgreifen
10.05.2017 22:22:06
Website
Hallo Anton,
danke für den Link. Den kannte ich noch nicht. Ich habe mich bisher vor allem über die DOM Dokumentation informiert, um meine Ziele bezüglich des Auslesens von Webseiten zu erreichen.
DOM Dokumentation:
https://msdn.microsoft.com/en-us/library/hh772384(v=vs.85).aspx
Ich habe aber in der Vergangenheit auch mal nachgesehen, was die Nummern von ReadyState eigentlich bedeuten. Aufgrund dessen und auch nach dem Folgen Deines Links und dem Lesen, was Busy bewirkt, gehe ich weiterhin davon aus, dass eine der beiden Warteoptionen einmal angewendet reicht.
Beide Parameter beziehen sich auf ein Object. Ich gehe davon aus, dass es sich bei diesem Object nicht um die Applikation Internet Explorer handelt, sondern um das Document, das in den Browser geladen wird, bzw. bei Busy noch, dass es sich um einen angestoßenen Download handelt.
Busy
https://msdn.microsoft.com/en-us/library/aa752050(v=vs.85).aspx
Hier heißt es unter Remarks:
If the control is busy, you can use the Stop method to cancel the navigation or download operation before it is completed.
Busy bezieht sich also auf die Navigation oder einen Download. Beides kann erst stattfinden, wenn der IE vollständig gestartet wurde.
ReadyState
https://msdn.microsoft.com/en-us/library/bb268229(v=vs.85).aspx
Hier beziehen sich alle möglichen Angaben nach meinem Dafürhalten ebenfalls auf das Document Object. Ich gehe mal nur auf READYSTATE_COMPLETE ein. (Das entspricht der Angabe 4)
Object has received all of its data.
Hier könnte man denken, Object bezieht sich auf den IE. Ich gehe aber auch hier davon aus, dass es sich um das Document Object handelt und bedeutet, es wird True zurück geliefert, wenn das Document vollständig geladen wurde.
Das begründe ich mit folgendem Code Abschnitt:

Set ie = CreateObject("internetexplorer.application")
URL = "https://www.ganztolleadresse.xy"
With ie
.Visible = True
.navigate URL
Do While .readyState  4
DoEvents
Loop
End With

In der ersten Zeile Set ie = CreateObject("internetexplorer.application"), wird der IE gestartet und für das Makro zu Verfügung gestellt. Im With ie Abschnitt wird bereits mit dieser Instanz des IE gearbeitet. Wäre er nicht vollständig geladen, wie sollte ihm dann die URL über die Zeile .navigate URL übergeben werden?
Alternativ könnte der IE auch erst instanziert werden, wenn bekannt ist, ob es Parameter gibt, mit denen er gestartet werden soll, indem diese danach angegeben werden. Es wäre aber eine recht komische Vorgehensweise, diese dann vom Aufruf komplett abzutrennen.
Hast Du mal getestet, ob sich Deine Makros noch so verhalten, wie sie sollen, wenn Du nur mit einer "Warteanweisung" arbeitest? Vielleicht magst Du das mal mit einem oder zweien ausprobieren. Würde mich echt interessieren.
Viele Grüße,
Zwenn
Anzeige
AW: Per VBA Daten von Website abgreifen
12.05.2017 16:11:59
Website
Hallo Zwenn,
ich habe ein paar meiner alten Scripten getestet und festgestellt, dass du Recht hast.
Die laufen jetzt nur mit einer Warteanweisung.Mir scheint so, dass MS einiges im IE geändert hat,
weil früher (ich bastele an solchen Scripten seit etwa 2005) musste ich 3x auf IE warten.
Vor allem hat mich immer irritiert, warum .Busy 2x durchlaufen muss, aber anders ging es auch nicht.
Was ich jetzt auch festgestellt habe, dass die Anweisung, so wie du das hier vorgeschlagen hast,
nicht mehr funktioniert und zum Fehler 424 führt, wenn die Seite kein Element mit der ID hat.
Google-Seite hat so einen Element nicht, deswegen läuft der Code von Marco in diesen Fehler.
mfg Anton
Anzeige

303 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige