Web Scraping mit VBA: Aktuelle Aktienkurse nach Excel importieren

Web Scraping VBA

Inhalt

Web Scraping VBA

Über den automatisierten Import von Aktienkursen nach Excel (seien es historische Kurse oder Echtzeitdaten) hatte ich ja auf DIY Investor schon des Öfteren mal geschrieben. Bisher ging es dabei allerdings ausschließlich um den Import von .csv Dateien, die über eine “offizielle” API des jeweiligen Seitenbetreibers (Yahoo Finance, Google Finance, Alpha Vantage) zur Verfügung gestellt wird (oder wurde) bzw. um den Import von Wechselkursen per Query. Nun habe ich mich zum ersten Mal auch mit dem so genannten Web Scraping mit VBA (Visual Basic for Applications, der in Excel und die anderen Office-Produkte integrierten Programmiersprache) befasst.

In diesem Artikel möchte ich euch einmal eine erstes einfaches Tool vorstellen, mit dem ihr Aktienkurse direkt und ohne die Nutzung irgendeiner API aus dem Netz ziehen könnt. Es soll dabei zunächst darum gehen, die Grundzüge des Web Scraping mit VBA zu erläutern. In der Folge werde ich dann noch weitere Details hinzufügen und ergänzen, sodass wir am Ende (hoffentlich) ein sehr gut in der Praxis nutzbares Tool haben.

Disclaimer: Ich hab noch nie ein Buch zum Thema VBA gelesen und kann auch nicht von mir behaupten, ein toller Programmierer zu sein. Insofern basiert alles, was ich hier schreibe auf Learning by Doing und es gibt mit Sicherheit viele da draußen, die sich weitaus besser mit VBA auskennen.


Vorab: Den Reiter “Entwicklertools” sichtbar machen

Im allerersten Schritt müssen wir in Excel den Reiter “Entwicklertools” bzw. “Developer” sichtbar machen. Wie das geht, habe ich bereits in meinem Artikel zum Import von historischen Kursdaten mithilfe der Yahoo Finance API erläutert.

Den Reiter Entwicklertools benötigen wir übrigens, um in Excel überhaupt ein Makro aufzeichnen oder schreiben zu können. Bei den meisten von euch wird dieser Reiter in der Excel Menüleiste standardmäßig aber nicht vorhanden bzw. nicht aktiviert sein.

Zum Aktivieren gehen wir also in unserem Excel zunächst auf Datei, dann auf Optionen. Über die Auswahl Menüband anpassen (Customize Ribbon) erhalten wir dann die folgende Ansicht:

Entwicklertools aktivieren - Web Scraping mit VBA

Wir müssen nun in der entsprechenden Hauptregisterkarte das Kontrollkästchen für die Entwicklertools (Developer) aktivieren und mit OK bestätigen.

Nun solltet ihr den Reiter “Entwicklertools” / “Developer” oben in der Menüleiste sehen können:

entwicklertools-aktiv - Web Scraping mit VBA

Soweit so gut.


Web Scraping mit VBA – Erste Schritte

Im nächsten Schritt öffnen wir die Entwicklertools und klicken anschließen ganz links auf die Schaltfläche Visual Basic.

Web Scraping - Visual Basic

Anschließend fügen wir ein neues Modul ein:

Haben wir das Modul einmal erstellt, können wir in der linken Leiste darauf klicken. Es öffnet sich ein neues Fenster, in dem wir anfangen können, unseren Code zu schreiben.

Für dieses Makro benötigen wir übrigens erstmal keine weiteren Bibiliotheken, Referenzen oder Converter. Wir können also tatsächlich direkt loslegen.


Den aktuellen Aktienkurs mithilfe von Web Scraping nach Excel importieren

Im Grunde genommen braucht ihr für eine erste Version eures Web Scraping Makros keine großartigen Programmierkenntnisse zu haben. Die Syntax von VBA erschließt sich einem ziemlich schnell und im Zweifel könnt ihr euch immer in Nullkommanix im Internet zu bestimmten Code-Schnipseln schlau machen.

Die wesentlichen Bestandteile unseres ersten Makros zum Download aktueller Aktienkurse mittels Web Scraping in VBA möchte ich hier aber trotzdem kurz vorstellen. Zunächst mal soll das Makro einfach nur den Aktienkurs eines Unternehmens (den Ticker tragen wir in Zelle A1 ein) in die Zelle B1 schreiben. Und das wars. Ziemlich simpel, aber für die Erläuterung der Logik vermutlich am übersichtlichsten.

Im ersten Schritt definieren wir die Hülle unseres Makros bestehend aus der Sub-Prozedur Sub und End Sub. Zwischen diese beiden Befehle schreiben wir alles, was noch folgt.

[vb] Sub Aktienkurs()

End Sub[/vb]

Anschließend legen wir schonmal ein paar Variablen fest, die wir für unser kleines Web Scraping Tool benötigen. Neben einem Objekt für den Browser (appIE) benötigen wir noch einen String (also eine Zeichenkette) namens ticker zum Auslesen des ausgewählten Tickersymbols aus Excel sowie einen String names myValue, in den wir später das Ergebnis des Web Scrapings, also den letzten Schlusskurs reinschreiben.

[vb] Dim appIE As Object
Dim ticker As String
Dim myValue As String
[/vb]

Nun weisen wir der ticker Variable schonmal den Inhalt der Zelle A1 unseres Excelsheets zu. Dieser soll später über eine Verknüpfung mit der entsprechenden URL von Yahoo Finance auf die richtige Webseite führen.

[vb] ticker = Range("A1")
[/vb]

So. Das war erstmal das Vorgeplänkel. Jetzt geht’s aber dann ans Eingemachte.

Zunächst mal benötigen wir für das Surfen im Internet natürlich einen Browser. Wir generieren also mithilfe unseres Codes einen Internet Explorer Browser. Dafür hatten wir oben bereits das Objekt appIE deklariert.

[vb] Set appIE = CreateObject("internetexplorer.application")
[/vb]

Anschließend können wir noch festlegen, wo auf unserem Screen das Browserfenster erscheinen und wie groß dieses sein soll. In diesem Fall erscheint das Fenster in der linken oberen Ecke und hat eine Breite von 800 und eine Höhe von 600 Pixeln. Über die Property Visible können wir außerdem festlegen, ob das Browserfenster während des Ausführens der Applikation zu sehen sein soll (True) oder nicht (False).

[vb] appIE.Top = 0
appIE.Left = 0
appIE.Width = 800
appIE.Height = 600
appIE.Visible = True
[/vb]

Anschließend bitten wir den Browser, auf unsere Zielseite zu gehen. Für die Aktie Microsoft ist dies z.B.:

https://finance.yahoo.com/quote/MSFT?p=MSFT

Dies können wir nach der bekannten Logik noch automatisieren bzw. mit einer Inputzelle im Excel (in diesem Fall die Zelle A1) verknüpfen. Zu diesem Zweck hatten wir weiter oben bereits die Variable ticker definiert und ihr die Zelle A1 unseres Excelsheets zugewiesen.

[vb] With appIE
.Navigate "https://finance.yahoo.com/quote/"& ticker & "?p=" & ticker & ""
.Visible = True
End With
[/vb]

Die Property Visible = True sorgt hier wieder dafür, dass das Browserfenster erstmal angezeigt wird. Dies könnt ihr aber eigentlich hier auch weglassen, weil es weiter oben auch schon steht.

Als Nächstes warten wir ab, bis der Browser die Seite komplett geladen hat:

[vb] Do While appIE.Busy
DoEvents
Loop
[/vb]

So. Nun da die Seite komplett geladen ist, greifen wir mithilfe der Methode getElementsByClassName auf das entsprechende Element auf der Seite zu:

[vb] Set allRowOfData = appIE.document.getElementsByClassName("Ta(end) Fw(b) Lh(14px)")
[/vb]

Das was da rechts in der Klammer steht (“Ta(end) Fw(b) Lh(14px)”) ist der Name der Klasse auf der Webseite, in der der Aktienkurs sozusagen drinliegt und auf die wir zugreifen möchten.

Es muss sich nicht immer zwangsläufig um eine Klasse handeln. Eine ID wäre z.B. auch möglich. In diesem Fall würden wir dann die Methode getElementbyID nutzen.

Wir kommen wir nun an diesen Klassennamen bzw. wie finden wir den genauen Ort heraus, an dem die von uns für das Web Scraping vorgesehenen Daten liegen?

Um das zu beantworten, verwenden wir die so genannten Entwicklertools unseres Browsers… zunächst gehen wir aber mal auf die Webseite, auf der unser Aktienkurs zu finden ist. Wir möchten nun gerne den Schlusskurs vom letzten Tag in unser Excel ziehen. Wie ihr sehen könnt, ist dieser in der Tabelle direkt oben links zu finden.

Um nun herauszufinden, wo unsere Applikation suchen soll, klicken wir mit der rechten Maustaste auf den ausgewählten Preis und wählen ganz unten den Punkt “Untersuchen” aus bzw. drücken einfach die F12-Taste (bei anderen Browsern kann das leicht anders aussehen und anders heißen):

Webseite untersuchen - Web Scraping mit VBA

Anschließend poppt unten folgendes Fenster auf:

Ihr sehr dort bereits das td -Element markiert, in welchem der letzte Schlusskurs zu finden ist. Wie ihr seht, ist die Logik universell anwendbar. Wollten wir anstelle des letzten Aktienkurses lieber das P/E Ratio ziehen, dann brauchen wir nur den zugehörigen Klassennamen zu finden, um die Zahl zu lokalisieren.

Nun da wir das richtige Element auf der Seite gefunden haben, müssen wir aus diesem Element noch den Aktienkurs extrahieren. Dies tun wir, indem wir die erste Zeile des Elements (mit der laufenden Nummer 0) in die Variable myValue schreiben:

[vb] myValue = allRowOfData(0).innerText
[/vb]

Haben wir das gemacht, dann können wir den Browser eigentlich schließen und das zugehörige Objekt appIE leeren.

[vb] appIE.Quit

Set appIE = Nothing
[/vb]

Das letzte was wir nun noch machen müssen, bevor wir die Applikation komplett beenden können, ist, den Aktienkurs in die entsprechende Zelle (nämlich B1) in unserem Excelsheet zu schreiben:

[vb] Range("B1").Value = myValue
[/vb]

Hier noch einmal der gesamte Code:

[vb]Sub Aktienkurs()

Dim appIE As Object
Dim ticker As String
Dim myValue As String

ticker = Range("A1")

Set appIE = CreateObject("internetexplorer.application")

appIE.Top = 0
appIE.Left = 0
appIE.Width = 800
appIE.Height = 600
appIE.Visible = True

With appIE
.Navigate "https://finance.yahoo.com/quote/" & ticker & "?p=" & ticker & ""
.Visible = True
End With

Do While appIE.Busy
DoEvents
Loop

Set allRowOfData = appIE.document.getElementsByClassName("Ta(end) Fw(b) Lh(14px)")

myValue = allRowOfData(0).innerText

appIE.Quit

Set appIE = Nothing

Range("B1").Value = myValue

End Sub[/vb]

Zum Abschluss können wir noch einen Button im Excelsheet hinzufügen, um das Makro auch von dort aus ausführen zu können. Dazu gehen wir im Reiter Entwicklertools auf Einfügen, wählen dann unter ActiveX Controls den Button aus und fügen diesen an beliebiger Stelle auf unserem Tabellenblatt ein:

Web Scraping VBA - Button einfügen

Durch einen Doppelklick auf den Button öffnet sich wieder unser Visual Basic Fenster und wir können den Code, den der Button bei Klick ausführen soll wie folgt formulieren:

[vb]Private Sub CommandButton1_Click()

Aktienkurs

End Sub[/vb]

Bei einem Klick auf den Button wird also dann das Makro Aktienkurs ausgeführt, welches wir weiter oben definiert hatten. Wir brauchen dann also nicht mehr in den VBA-Editor zu gehen, um das Makro auszuführen.


Nächste Schritte

Als nächsten Schritt wäre eine Erweiterung des Makros sinnvoll, sodass gleichzeitig nicht nur ein, sondern beliebig viele Aktienkurse von verschiedenen Unternehmen mit verschiedenen Tickern heruntergeladen werden. Auf diese Erweiterung werde ich in Kürze etwas näher eingehen.

14 Kommentare zu „Web Scraping mit VBA: Aktuelle Aktienkurse nach Excel importieren“

  1. Schön erklärt! Noch ein paar Tipps: Wenn du in den Verweisen des VBA-Editors (Menü Extras) die Microsoft Internet Controls und die HTML Object Library einbindest, hast du eine richtig gute Syntaxunterstützung (Intellisense) und eine bessere Deklarationsmöglichkeit als As Object, z.B. appIE as InternetExplorer usw. Weiterhin funtioniert anstelle von Do While appIE.Busy die ganze Sache stabiler mit Do Until appIE.ReadyState = 4 (bzw. Konstante READYSTATE_COMPLETE, sofern du die Internet Controls eingebunden hast).
    Wenn du nur mal eben einen Kurs abrufen willst, ist das so, wie du es gezeigt hast, OK. Für ganze Listen wäre es dann aber sinnvoll, noch ein Errorhandling einzubauen für den Fall, dass das mit dem Seitenaufruf im IE mal nicht so funktioniert, um da sauber wieder rauszukommen, ohne dann den Task “mit Gewalt” beenden zu müssen.

  2. Coole Anleitung! Bin gespannt wie es weiter geht. Ich habe auch schon einiges mit VBA-Webscraping gemacht. Vornehmlich waren für mich für einige Zeit die Quartalszahlen-Termine von Interesse.
    Beste Grüße
    Alexander

  3. Hallo zusammen,
    vielen dank. Für Yahoo konnte ich durch mehrere Module verschiedene Kurse abrufen.
    Kann ich die Einbindung auch über ariva.de durchführen? Wie komme ich hier an den Kurs. Kenne mich leider mit VBA nicht so aus. Seite einbinden, anstelle von Yahoo, bekomme ich noch hin. Aber nicht den Tageskurs.

    Grüße D.

    1. Hallo Dennis,

      theoretisch sollte das auch für Avira.de funktionieren. Du musst halt nur wissen, wo (in welcher ID oder Klasse) der Kurs auf der Seite zu finden ist. Dazu nutzt du die “untersuchen”-Funktion deines Browsers wie oben beschrieben.

      Viele Grüße,
      Axel

  4. Top Erklärung!

    Eine Frage ist mir bei der Anwendung aufgetaucht.
    Wenn ich den Befehl über getElementybyID ausführen will, welche ID muss ich hier nutzen? Wenn ich über untersuchen gehe sehe ich bei Yahoo Finance nur eine reactid. Hier kurz am Beispiel von dem aktuellen Kurswert dargestellt:

    wenn ich dann
    ‘Set allRowOfData = appIE.document.getElementbyID(“40”) ausführen möchte erfolgt eine Fehlermeldung.

    Die Frage kommt daher, dass ich gemerkt habe, dass wenn man z. B. das Handelsvolumen abfragen möchte der ClassName der Gleiche ist wie z. B. beim aktuellen Wert.

    Daher dachte ich, dass man ggf. über die ID eine Unterscheidung erhält, um mehrere Werte gleichzeitig abzufragen.

    Schonmal vielen Dank für die Rückmeldung.

    VG, Nicolas

    1. Hi Nicolas,

      ich denke dann müsstest du die ID nehmen, die in der Struktur der Webseite auf der Ebene darüber angesiedelt ist. Zusätzlich müsstest du dann der Routine aber noch sagen, wie sie von der ID aus das gewünschte Element erreicht.

      Viele Grüße,
      Axel

  5. Wow, danke für die tolle Anleitung. Ist es auch möglich ein Bild von der Website einzufügen? Die Information die ich suche (Rating eines Fonds) ist leider als Bild auf der Seite dargestellt. Wie muss ich in diesem Fall mit

    Set allRowOfData = appIE.document.getElementsByClassName(“Ta(end) Fw(b) Lh(14px)”)

    weiter vorgehen?

    Danke schon mal.

    1. Hallo! Mir ist leider nicht bekannt, dass Bilder auch ausgelesen werden können… aber ich habe mich damit ehrlich gesagt auch bisher noch nicht befasst.

      Viele Grüße,
      Axel

  6. Hallo Axel,
    habe heute den VBA-Code getestet. Leider kommt bei der Anweisung
    myValue = allRowOfData(0).innerText
    folgende Fehlermeldung:

    Laufzeitfehler ’91’: Objektvariable oder With-Blockvariable nicht festgelegt

    Viele Grüße
    Heinz

  7. Guten Tag
    Herzlichen Dank für das Tutorial
    Ich möchte am Schluss gerne das VBA Automatisch neu starten und ticker Range A1 sowie Range B1 am Schluss um +1 Erhöhen damit er bei neu start den link aus A2 nimmt und den Wert in B2 schreibt das müsste ich 9000x Ausführen.
    gibt es da eine möglichkeit?

  8. Hallo Axel,
    vielen Dank für das gute Tutorial.
    Leider habe ich das gleiche Problem wie Heinz Lindner mit dem Laufzeitfehler “91” an der selben Stelle. Hast Du da noch einen Tipp für uns?
    Viele Grüße
    Manfred

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Weitere relevante Artikel zum Thema

Warenkorb
Nach oben scrollen