AW: VBA web scraping nochmal
09.05.2019 11:14:52
Zwenn
Hallo Torsten,
wenn Du alle PlayerIDs durchgehen willst, funktioniert das auch mit For Each. Um Alle PlayerIDs in einer NodeList einzusammeln, musst Du den direkten Zugriff auf ein bestimmtes Element der Liste weglassen. Mit (0) am Ende greifst Du direkt auf das erste Element zu und bildest nur damit das Objekt knoten. Wenn Du (0) weglässt, wird eine Liste mit allen Elementen der Klasse ol-player-name gebildet, die Du dann mit For Each durchgehen kannst.
Die nachgestellte (0) ist schon der Index auf das erste Element. Wenn Du die Zeile mit so einem Index schreibst, wird genau dieses Element zurückgeliefert.
Für Dein spezifisches Beispiel heißt das:
Set knoten = browser.document.getElementsByClassName("ol-player-name")(0)
Ergibt Spieler 1:
<span onclick="olAnchorNavigation.load('player/overview', { playerId: 3701 });" class="ol- _
player-name">Spieler 1</span>
Set knoten = browser.document.getElementsByClassName("ol-player-name")(1)
Ergibt Spieler 2:
<span onclick="olAnchorNavigation.load('player/overview', { playerId: 3702 });" class="ol- _
player-name">Spieler 2</span>
Set knoten = browser.document.getElementsByClassName("ol-player-name")(4)
Ergibt Spieler 5:
<span onclick="olAnchorNavigation.load('player/overview', { playerId: 27219 });" class="ol- _
player-name">Spieler 5</span>
Das Prinzip sollte klar sein. Wenn Du nun die ganze Liste brauchst, dann geht das so:
Set knoten = browser.document.getElementsByClassName("ol-player-name")
Ergibt Liste von Spieler 1 bis Spieler 28 mit den Indizes 0 bis 27:
<span onclick="olAnchorNavigation.load('player/overview', { playerId: 3701 });" class="ol- _
player-name">Spieler 1</span>
<span onclick="olAnchorNavigation.load('player/overview', { playerId: 3702 });" class="ol- _
player-name">Spieler 2</span>
<span onclick="olAnchorNavigation.load('player/overview', { playerId: 52869 });" class="ol- _
player-name">Spieler 28l</span>
Im letzten Posting habe ich Dir erklärt, wie Du eine Seite eindeutig identifizieren kannst und Du hast das auch gut umgesetzt. Du brauchst diese Identifizierung aber nur, wenn Du mit der identifizierten Seite etwas anstellen willst. Das willst Du in Deinem Fall nicht. Also kannst Du Dein Makro vereinfachen, indem Du direkt auf die CSS-Klasse ol-player-name abfragst. Wenn sie vorhanden ist, wird das Objekt knoten gebildet, wenn nicht, dann nicht.
Naja, jedenfalls dachte ich das bisher. Ich habe das Makro unten so geschrieben, wie ich es grade erklärt habe. Es wird aber komischerweise auch ein Objekt knoten gebildet, wenn kein Tag diese CSS-Klasse hat. Ich weiß nicht warum, aber man bekommt in diesem Fall eine leere NodeList zurückgeliefert. Die Länge einer NodeList kann man jedoch abfragen, was wir hier für die Prüfung ausnutzen.
Wir nehmen in diesem Fall statt:
If Not knoten Is Nothing then
die Zeile
If knoten.Length > 0 then
Deine Stringbearbeitung habe ich so gelassen, sie funktioniert ja super. Ich habe lediglich die Zusammensetzung der Variable ergebnis so angepasst, dass alle PlayerIDs untereinander ausgegeben werden:
Sub WerteAuslesen()
'Variablen deklarieren
Dim url As String
Dim browser As Object
Dim knoten As Object
Dim knotenPlayer As Object
Dim htmlText As String
Dim splitArray() As String
Dim ergebnis As String
'Adresse der auszulesenden Seite
url = "https://trainingslager.onlineliga.de/team/overview/squad?userId=196"
'Internet Explorer initialisieren, Sichtbarkeit festlegen,
'URL aufrufen und warten bis Seite vollständig geladen wurde
Set browser = CreateObject("internetexplorer.application")
browser.Visible = False
browser.Navigate url
Do Until browser.ReadyState = 4: DoEvents: Loop
'Knotenobjekt setzten
Set knoten = browser.document.getElementsByClassName("ol-player-name")
'Abfrage ob Seite mit TeamID auch SpielerIDs enthält
If knoten.Length > 0 Then
'Wenn Klasse "ol-player-name" vorhanden ist,
'existiert die abgefragte TeamID
'Alle PlayerIDs zur TeamID auslesen
For Each knotenPlayer In knoten
'Text in Variable schreiben
htmlText = knotenPlayer.outerHTML
'Klammer im gefundenen Text umbenennen,
'damit die spätere Split-Funktion nur einen Delimiter hat
'Vordere Klammer umbennenen
htmlText = Replace(htmlText, "{", "@")
'Hintere Klammer umbennenen
htmlText = Replace(htmlText, "}", "@")
'Gefundenen Text splitten und in ein Array schreiben
splitArray = Split(htmlText, "@")
'Überflüssigen Text im richtigen Array durch Leerzeichen ersetzen,
'alle Leerzeichen wegschneiden,
'restlichen Text in Ergebnisvariable übergeben
ergebnis = ergebnis & Trim(Replace(splitArray(1), "playerId:", " ")) & Chr(13)
Next knotenPlayer
Else
'Wenn Klasse "ol-player-name" nicht vorhanden ist,
'ist die abgefragte TeamID nicht vorhanden
ergebnis = "Es gibt kein Team mit der angegebenen ID"
End If
'Ergebnis in MsgBox ausgeben
MsgBox ergebnis
'Aufräumen
ergebnis = ""
browser.Quit
Set browser = Nothing
Set knoten = Nothing
Set knotenPlayer = Nothing
End Sub
Viele Grüße,
Zwenn