🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA Web Scraping in Excel — Daten von einer Website abrufen, ohne Internet Explorer

|

VBA Web Scraping in Excel — Daten von einer Website abrufen, ohne Internet Explorer

TL;DR — Ein Scraping-Makro erhält das HTML, das der Server gesendet hat, nicht die Seite, die Sie sehen. Ihr Browser führt JavaScript aus, nachdem die Seite angekommen ist, und baut oft erst dann die Tabelle, die Sie haben wollen; in dem, was VBA herunterlädt, taucht sie deshalb nie auf. Prüfen Sie zuerst: Öffnen Sie Seitenquelltext anzeigen (Strg+U) und suchen Sie nach einem Wert, den Sie brauchen. Steht er dort, laden Sie die Seite mit XMLHTTP herunter und lesen sie mit einem htmlfile-Dokument. Steht er dort nicht, lädt die Seite ihre Daten über eine JSON-Anfrage, und diese Anfrage direkt aufzurufen ist einfacher und stabiler als jedes Scraping. Die Automatisierung von Internet Explorer ist keine Option mehr.

Dim http As Object, doc As Object
Set http = CreateObject("MSXML2.XMLHTTP.6.0")
http.Open "GET", "https://example.com/prices", False
http.send
Set doc = CreateObject("htmlfile")
doc.body.innerHTML = http.responseText
Debug.Print doc.getElementsByTagName("table").Length & " tables found"

Dies ist der dritte Artikel einer Reihe darüber, Daten aus dem Web nach Excel zu holen: VBA HTTP Request behandelt die Anfrage, VBA JSON die strukturierte Antwort und dieser Artikel Seiten, die für Menschen statt für Code geschrieben wurden. Die Idee der Reihe: Eine Web-Anfrage liefert Ihnen Text, keine Daten. Zwischen dem Server und Ihren Zellen liegen drei Übersetzungen, für die Sie verantwortlich sind: Bytes zu Text, Text zu Struktur, Struktur zu Raster. Scraping ist die Variante, bei der die Struktur nie für Sie gedacht war.

Was Sie lernen

  • Das mentale Modell: das HTML, das der Server gesendet hat
  • Der Zehn-Sekunden-Test: Seitenquelltext anzeigen
  • Wenn die Daten nicht im Quelltext stehen: das JSON finden
  • Warum nicht Internet Explorer oder Selenium
  • Eine HTML-Tabelle mit htmlfile lesen
  • Ausgelesene Zahlen sind Text
  • Verstümmelter Text durch ein meta charset
  • Power Query und höfliches Scraping

Das mentale Modell: das HTML, das der Server gesendet hat

Ein Browser macht mit einer Seite zwei Dinge. Er lädt das HTML herunter, und dann führt er das JavaScript der Seite aus, das oft weitere Daten abruft und Tabellen, Preise und Listen auf dem Bildschirm aufbaut. Was Sie sehen, ist das Ergebnis beider Schritte. Was VBA mit einer HTTP-Anfrage herunterlädt, ist nur der erste Schritt: das HTML, so wie der Server es gesendet hat.

Deshalb lautet die häufigste Scraping-Beschwerde: „Mein Code findet keine Tabelle, aber ich sehe die Tabelle doch.“ Beide Aussagen stimmen. Die Tabelle existiert in der lebendigen Seite des Browsers, nicht im HTML, das der Server gesendet hat. Kein Selektor, kein Warten und kein erneuter Versuch ändert daran etwas, denn die Daten waren nie in dem, was Sie heruntergeladen haben.

Der Zehn-Sekunden-Test: Seitenquelltext anzeigen

Bevor Sie Code schreiben, öffnen Sie die Seite in einem Browser und drücken Strg+U (Seitenquelltext anzeigen). Das zeigt das HTML so, wie der Server es gesendet hat, also genau das, was VBA erhalten wird. Durchsuchen Sie es (Strg+F) nach einem Wert, den Sie auf der Seite sehen, etwa einem Preis oder einem Namen.

  • Gefunden: Die Daten stehen im HTML des Servers. Lesen Sie sie mit XMLHTTP und htmlfile aus, siehe unten.
  • Nicht gefunden: JavaScript lädt sie. Weiter mit dem nächsten Abschnitt.

Verwenden Sie für diesen Test nicht Untersuchen (F12, Elemente). Untersuchen zeigt die lebendige Seite, nachdem JavaScript gelaufen ist, und zeigt die Daten deshalb in beiden Fällen.

Wenn die Daten nicht im Quelltext stehen: das JSON finden

Eine Seite, die ihre Tabelle mit JavaScript aufbaut, muss die Daten irgendwoher bekommen, fast immer über eine JSON-Anfrage an dieselbe Website. So finden Sie sie:

  1. Öffnen Sie die Entwicklertools des Browsers (F12) und wechseln Sie zum Tab Netzwerk.
  2. Filtern Sie nach Fetch/XHR und laden Sie die Seite neu.
  3. Klicken Sie die Anfragen an und sehen Sie sich jeweils die Antwort an. Eine davon enthält Ihre Daten als JSON.
  4. Kopieren Sie deren URL und rufen Sie sie aus VBA auf, wie in VBA HTTP Request gezeigt, und parsen Sie sie dann mit VBA JSON.

Dieser Weg ist besser als Scraping, selbst wenn Scraping funktionieren würde. Das JSON hat Feldnamen statt Tabellenpositionen, Zahlen ohne Währungssymbole, und es ändert sich seltener als das Seitendesign. Prüfen Sie die Nutzungsbedingungen der Website, bevor Sie darauf aufbauen; ein undokumentierter Endpunkt kann sich außerdem ohne Vorankündigung ändern.

Warum nicht Internet Explorer oder Selenium

Ältere Tutorials steuern aus VBA einen Browser mit CreateObject("InternetExplorer.Application"). Internet Explorer wurde im Juni 2022 eingestellt; er wird nicht mehr unterstützt, und moderne Websites funktionieren darin immer öfter nicht. Beginnen Sie darauf keine neue Arbeit, und planen Sie, Makros zu ersetzen, die davon abhängen.

Selenium Basic, der übliche Ersatz für VBA, hat seit 2016 kein Release mehr bekommen und braucht einen Browsertreiber, der zur installierten Chrome- oder Edge-Version passt; jedes Browser-Update kann das Makro auf dem Rechner des Benutzers kaputtmachen. Für eine Seite, die nur mit JavaScript funktioniert und keine Datenanfrage hat, die Sie aufrufen können, kann es trotzdem das richtige Werkzeug sein, aber betrachten Sie es als letzten Ausweg, nicht als Standard.

Eine HTML-Tabelle mit htmlfile lesen

Für Daten, die im HTML des Servers stehen, brauchen Sie keinen Browser. Laden Sie die Seite herunter und in ein htmlfile-Objekt, das Ihnen ein Dokument liefert, das Sie wie eine Webseite durchsuchen können:

Sub ScrapeFirstTable(ByVal url As String, ByVal target As Range)
    Dim http As Object, doc As Object, tbl As Object
    Dim out() As Variant, r As Long, c As Long, nCols As Long

    Set http = CreateObject("MSXML2.XMLHTTP.6.0")
    http.Open "GET", url, False
    http.setRequestHeader "User-Agent", "Mozilla/5.0"
    http.send
    If http.Status <> 200 Then Err.Raise vbObjectError + 514, , "HTTP " & http.Status

    Set doc = CreateObject("htmlfile")
    doc.body.innerHTML = http.responseText
    If doc.getElementsByTagName("table").Length = 0 Then Err.Raise vbObjectError + 515, , "No table"
    Set tbl = doc.getElementsByTagName("table")(0)

    nCols = 0
    For r = 0 To tbl.Rows.Length - 1
        If tbl.Rows(r).Cells.Length > nCols Then nCols = tbl.Rows(r).Cells.Length
    Next r
    ReDim out(1 To tbl.Rows.Length, 1 To nCols)
    For r = 0 To tbl.Rows.Length - 1
        For c = 0 To tbl.Rows(r).Cells.Length - 1
            out(r + 1, c + 1) = Trim$(tbl.Rows(r).Cells(c).innerText)
        Next c
    Next r
    target.Resize(UBound(out, 1), nCols).Value = out
End Sub

Drei Details sind wichtig. Die Auflistungen aus dem HTML-Dokument (Rows, Cells, getElementsByTagName) beginnen bei 0, anders als das meiste in Excel. Zeilen können unterschiedlich viele Zellen haben, also bemessen Sie das Array nach der breitesten Zeile. Und die ganze Tabelle wird in einem Schritt ins Blatt geschrieben.

Um ein bestimmtes Element zu finden, verlassen Sie sich auf getElementById und getElementsByTagName. Je nach Windows- und Office-Build kann ein spät gebundenes htmlfile-Dokument in einem alten Kompatibilitätsmodus laufen, in dem neuere Methoden wie querySelector und getElementsByClassName fehlen; Code, der darauf aufbaut, funktioniert dann auf dem einen Rechner und auf dem anderen nicht. Um nach Klasse zu filtern, durchlaufen Sie die Tags und prüfen .className.

„Die erste Tabelle“ auszuwählen ist die schwächste Stelle jedes Scrapers. Bei einem Redesign kommt über Ihrer Tabelle eine weitere hinzu, und das Makro liest stillschweigend die falsche. Hat die Tabelle eine id, verwenden Sie sie; andernfalls prüfen Sie den Text einer Kopfzelle, bevor Sie der Tabelle vertrauen.

Ausgelesene Zahlen sind Text

Alles, was Sie mit innerText von einer Seite holen, ist ein String, formatiert für die Leute, die diese Website lesen: 1.234,56 € auf einer deutschen Seite, 1 234,56 € auf einer französischen, $1,234.56 auf einer amerikanischen. Als Text in eine Zelle geschrieben, lässt es sich nicht summieren. Mit CDbl oder Val umgewandelt, ergibt es je nach den Regionaleinstellungen des Benutzers eine falsche Zahl oder einen Fehler.

Wandeln Sie nach dem Format der Website um, nicht nach dem des Benutzers. Entfernen Sie die Währung und das Tausendertrennzeichen, machen Sie dann das Dezimaltrennzeichen zu einem Punkt und verwenden Sie Val:

Function ParseScraped(ByVal s As String, ByVal thousandsSep As String, ByVal decimalSep As String) As Variant
    s = Replace(s, ChrW(160), "")          ' geschuetztes Leerzeichen
    s = Replace(s, ChrW(8239), "")         ' schmales geschuetztes Leerzeichen
    s = Replace(s, " ", "")
    s = Replace(s, ChrW(8364), ""): s = Replace(s, "$", "")   ' Eurozeichen
    If thousandsSep <> "" Then s = Replace(s, thousandsSep, "")
    s = Replace(s, decimalSep, ".")
    If s Like "*[!0-9.-]*" Or s = "" Then ParseScraped = CVErr(xlErrValue) Else ParseScraped = Val(s)
End Function

v = ParseScraped(cellText, ".", ",")   ' "1.234,56" von einer deutschen Seite -> 1234.56

Die beiden geschützten Leerzeichen sind die versteckte Falle. Französische und andere europäische Websites trennen Tausender oft damit, sie sehen genau wie ein Leerzeichen aus, und Trim entfernt sie nicht. Dasselbe Zeichen in eingefügten Daten behandelt VBA Trim.

Verstümmelter Text durch ein meta charset

responseText dekodiert die Seite mit dem Zeichensatz aus dem HTTP-Header des Servers. Viele ältere Websites geben ihre Kodierung nur innerhalb des HTML an, mit einem <meta charset>-Tag, und XMLHTTP liest dieses Tag nicht. Die Seite sieht im Browser gut aus und kommt in VBA mit é statt é an oder mit Kästchen statt japanischem Text.

Enthält der Quelltext ein Tag <meta charset="windows-1252"> oder <meta charset="shift_jis"> und ist der Text verstümmelt, dekodieren Sie http.responseBody mit diesem Zeichensatz, mit der ADODB.Stream-Funktion aus VBA HTTP Request, und übergeben das Ergebnis an doc.body.innerHTML.

Power Query und höfliches Scraping

Für eine statische HTML-Tabelle, die Sie aktualisieren wollen, hat Excel bereits einen Scraper eingebaut: Daten > Aus dem Web (Power Query) listet die Tabellen einer Seite auf, lädt die gewählte und aktualisiert sie per Klick, ohne VBA. Es hat dieselbe Grenze, denn es liest ebenfalls das HTML des Servers, aber wenn es funktioniert, müssen Sie weniger Code pflegen. Nehmen Sie VBA, wenn Sie Logik brauchen: eine Liste von URLs, eine Anmeldung oder das Zusammenführen von Seiten.

Und scrapen Sie höflich. Eine Anfrage pro Seite, eine Pause zwischen den Seiten (siehe VBA Wait), nichts erneut herunterladen, was Sie schon haben, und vorher ein Blick in die Nutzungsbedingungen und die robots.txt der Website. Ein Makro, das hundert Anfragen pro Sekunde abfeuert, sorgt dafür, dass die IP-Adresse Ihres Büros gesperrt wird, und dann funktioniert niemandes Makro mehr.

Die Abwägung: Scraping ist ein Vertrag, den niemand unterschrieben hat

Eine API ist ein Versprechen: Der Anbieter dokumentiert sie und bemüht sich, sie nicht zu brechen. Eine Webseite verspricht nichts. Der Designer kann morgen eine Tabelle hinzufügen, eine Klasse umbenennen oder die Preise in JavaScript verlagern, und Ihr Makro bricht ohne Fehlermeldung, oder schlimmer, es liest die falsche Spalte.

Wählen Sie also die stabilste verfügbare Quelle: zuerst eine offizielle API, dann die JSON-Anfrage hinter der Seite, dann Power Query auf einer statischen Tabelle, dann XMLHTTP mit htmlfile und die Browser-Automatisierung zuletzt. Was auch immer Sie wählen: Lassen Sie den Scraper prüfen, was er gefunden hat (einen Kopfzeilentext, eine Zeilenanzahl), bevor er schreibt, damit ein Redesign einen Fehler erzeugt statt falscher Zahlen.

Wie ExcelMaster hilft

Scraper gehen leise kaputt: Das Layout ändert sich, die Zahlen kommen im Format eines anderen Landes zurück, der Text kommt verstümmelt an.

ExcelMaster prüft, was der Server tatsächlich zurückgibt, bevor es den Code schreibt, sucht bei JavaScript-Seiten nach der Datenanfrage dahinter und wandelt ausgelesene Zahlen nach dem Format der Website um, damit sie als echte Zahlen in Ihrem Blatt ankommen.

Häufig gestellte Fragen

Wie lese ich mit VBA eine Website in Excel aus?

Laden Sie die Seite mit MSXML2.XMLHTTP.6.0 herunter, laden Sie responseText in CreateObject("htmlfile"), finden Sie die Tabelle mit getElementsByTagName("table"), lesen Sie das innerText jeder Zelle in ein Array und schreiben Sie das Array ins Blatt.

Warum findet mein VBA-Scraper Daten nicht, die ich auf der Seite sehe?

Die Seite baut diese Daten nach dem Laden mit JavaScript auf, also stehen sie nicht in dem HTML, das VBA herunterlädt. Suchen Sie die JSON-Anfrage im Tab Netzwerk des Browsers und rufen Sie sie direkt auf.

Kann ich für Web Scraping in VBA noch Internet Explorer verwenden?

Das ist nicht zu empfehlen. Internet Explorer wurde im Juni 2022 eingestellt und wird nicht mehr unterstützt. Verwenden Sie XMLHTTP mit htmlfile für statische Seiten und die JSON-Anfrage der Seite für dynamische.

Warum sind ausgelesene Zahlen in Excel keine Zahlen?

innerText liefert immer Text, formatiert für das Land der Website. Entfernen Sie Währungssymbole und Tausendertrennzeichen, einschließlich geschützter Leerzeichen, ändern Sie das Dezimaltrennzeichen in einen Punkt und wandeln Sie mit Val um.

Ist Power Query für Web Scraping besser als VBA?

Für eine statische Tabelle, die Sie aktualisieren wollen, ja: Daten > Aus dem Web braucht keinen Code. Nehmen Sie VBA, wenn Sie viele Seiten durchlaufen, sich anmelden oder zwischen den Anfragen Logik anwenden müssen.

Getestet in

Getestet in: Excel 365 (Windows 11), VBA 7.1 — zuletzt geprüft am 05.10.2026.

Verwandte Anleitungen: VBA HTTP Request · VBA JSON · VBA Trim · VBA Wait · VBA 2D-Array · VBA Replace · VBA Like · VBA CreateObject