Webscraper Öffnungszeiten

  • Excel

SSL ist deaktiviert! Aktivieren Sie SSL für diese Sitzung, um eine sichere Verbindung herzustellen.

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    Webscraper Öffnungszeiten

    Liebe Community,

    ich bin dabei einen Webscraper zu programmieren, der per HTTP Anfrage die Öffnungszeiten einer Filialkette sammeln soll, indem die komplette PLZ von ganz Deutschland immer wieder erneut eingetragen werden und alle Filialen im Bereich der jeweiligen PLZ aufgesammelt und in einer Excel Tabelle eingetragen werden.

    Der Link lautet wie folgt:
    Spoiler anzeigen
    https://filialfinder.aldi-sued.de/Presentation/AldiSued/de-de/Search?SingleSlotGeo=PLZ&Mode=None


    Bei der Ausführung erscheint der Laufzeitfehler '438': Objekt unterstützt diese Eigenschaft oder Methode nicht
    und es wird folgende Zeile markiert:

    Visual Basic-Quellcode

    1. Select Case Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open")(0).innerText


    Davor hat es immer folgende Zeile markiert:

    Visual Basic-Quellcode

    1. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 2).Value = Element.getElementsByClassName("resultItem-CompanyName")(0).innerText


    Ich habe bisher folgenden Code geschrieben (In der Excel Datei als Modulnamen "vb_paradise" eingetragen). Diesen Code findet ihr auch in der .xlsm-Datei (gepackt in der .rar-Datei, da .xlsm-Endung nicht akzeptiert wird):

    Visual Basic-Quellcode

    1. Sub Filialenliste()
    2. Dim PLZListe As Range: Set PLZListe = Worksheets("PLZ").Range("A2:A14957")
    3. Dim strPLZ As String
    4. Application.ScreenUpdating = False
    5. Dim i As Integer
    6. i = 2
    7. Dim Ortskreis As Object
    8. For Each Ortskreis In PLZListe
    9. strPLZ = "https://filialfinder.aldi-sued.de/Presentation/AldiSued/de-de/Search?SingleSlotGeo=" & Ortskreis & "&Mode=None"
    10. Dim MyHttpRequest As New WinHttpRequest
    11. MyHttpRequest.Open "Get", strPLZ, False
    12. MyHttpRequest.Send
    13. Dim strResponse As New MSHTML.HTMLDocument
    14. strResponse.body.innerHTML = MyHttpRequest.ResponseText
    15. If IsEmpty(strResponse) = True Then
    16. MsgBox "Keine Antwort von der Aldi-Seite erhalten! Bitte Verbindung und Verfügbarkeit der Seite überprüfen!"
    17. End If
    18. Dim Element As Object
    19. Dim Elements As Object
    20. Set Elements = strResponse.getElementsByClassName("col-xs-10")
    21. For Each Element In Elements
    22. If Not strResponse.getElementsByClassName("open")(0) Is Nothing Then
    23. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 1).Value = Ortskreis
    24. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 2).Value = Element.getElementsByClassName("resultItem-CompanyName")(0).innerText
    25. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 3).Value = Element.getElementsByClassName("resultItem-Street")(0).innerText
    26. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 4).Value = Element.getElementsByClassName("resultItem-City")(0).innerText
    27. Dim Oeffnungszeit As Object
    28. Set Oeffnungszeit = Element.getElementsByClassName("openingHoursTable")
    29. Select Case Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open")(0).innerText
    30. Case "Mo"
    31. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed openingTime")(0).innerText
    32. Case "Di"
    33. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed openingTime")(0).innerText
    34. Case "Mi"
    35. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed openingTime")(0).innerText
    36. Case "Do"
    37. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed openingTime")(0).innerText
    38. Case "Fr"
    39. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed openingTime")(0).innerText
    40. Case "Sa"
    41. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(0).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(1).getElementsByClassName("open openingTime")(0).innerText & vbCrLf & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed")(0).innerText & " " & Oeffnungszeit.getElementsByTagName("tr")(2).getElementsByClassName("closed openingTime")(0).innerText
    42. Case Else
    43. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = Element.getElementsByClassName("open")(0).innerText & " " & Element.getElementsByClassName("open openingTime")(0).innerText & vbCrLf & "So geschlossen"
    44. End Select
    45. Else
    46. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 1).Value = Ortskreis
    47. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 2).Value = "Kein Aldi in diesem PLZ"
    48. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 3).Value = "Kein Aldi in diesem PLZ"
    49. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 4).Value = "Kein Aldi in diesem PLZ"
    50. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = "Kein Aldi in diesem PLZ"
    51. End If
    52. i = i + 1
    53. Next
    54. Next
    55. Set MyHttpRequest = Nothing
    56. Set ALDIHTML = Nothing
    57. Set srtResponse = Nothing
    58. Application.ScreenUpdating = True
    59. End Sub


    Die benötigten Verweise habe ich schon ausgewählt.

    Was mache ich falsch?
    Dateien
    • Aldi.rar

      (513,45 kB, 7 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „fatony“ ()

    Als erstes würde ich darauf achten, dass deine PLZ-Spalte textformatiert ist und 5-stellige Postleitzahlen enthält.

    Und dann stimmt deine Dokumentanalyse wohl nicht.
    ​Element.getElementsByClassName("resultItem-CompanyName") existiert nicht.
    Vermutlich musst du durch die Children loopen, um an die Daten zu kommen.
    Oder ​Element.innerHTML manuell parsen.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „petaod“ ()

    petaod schrieb:

    Als erstes würde ich darauf achten, dass deine PLZ-Spalte textformatiert ist und 5-stellige Postleitzahlen enthält.


    vielen lieben dank für den Hinweis! Jetzt erscheinen auch ein paar Filialen mehr ;D für die anderen. Das Problem wurde folgendermaßen gelöst: Im Sheet PLZ habe ich eine neue Spalte erstellt und dort =TEXT(A1;"00000") eingetragen und dann doppelklicken, damit die Formel übertragen wird. Später im Code die Bezugszellen von A zu G ändern!

    petaod schrieb:


    Und dann stimmt deine Dokumentanalyse wohl nicht.
    Element.getElementsByClassName("resultItem-CompanyName") existiert nicht.



    wie kann das sein, dass obwohl "resultItem-CompanyName" nicht verfügbar ist, vba es doch erkennt und es in die Tabelle einträgt.

    petaod schrieb:


    Vermutlich musst du durch die Children loopen, um an die Daten zu kommen.Oder Element.innerHTML manuell parsen.


    Kannst du mir dazu eine Quelle geben? Ich google das, aber nirgendwo finde ich eine Quelle, die das näher erläutert...


    Ich habe den Code jetzt soweit geändert:
    Die Öffnungszeitenformatierung werde ich später ändern. Für mich ist erstmal wichtig, dass alles nötige heruntergeladen wird.
    Er zieht alles herunter, aber bleibt beim Sprung zur nächsten PLZ hängen mit dem Fehler "Objektvariable oder With-Blockvariable nicht festgelegt" (Laufzeitfehler '91') mit dem Verweis auf die folgende Zeile:

    Visual Basic-Quellcode

    1. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 2).Value = ElementHTML.getElementsByClassName("resultItem-CompanyName")(0).innerText


    Visual Basic-Quellcode

    1. Sub Filialenliste()
    2. Dim PLZListe As Range: Set PLZListe = Worksheets("PLZ").Range("G2:G14957")
    3. Dim strPLZ As String
    4. Application.ScreenUpdating = False
    5. Dim i As Integer
    6. i = 2
    7. Dim Ortskreis As Object
    8. For Each Ortskreis In PLZListe
    9. strPLZ = "https://filialfinder.aldi-sued.de/Presentation/AldiSued/de-de/Search?SingleSlotGeo=" & Ortskreis & "&Mode=None"
    10. Dim MyHttpRequest As New WinHttpRequest
    11. MyHttpRequest.Open "Get", strPLZ, False
    12. MyHttpRequest.Send
    13. Dim strResponse As New MSHTML.HTMLDocument
    14. strResponse.body.innerHTML = MyHttpRequest.ResponseText
    15. If IsEmpty(strResponse) = True Then
    16. MsgBox "Keine Antwort von der Aldi-Seite erhalten! Bitte Verbindung und Verfügbarkeit der Seite überprüfen!"
    17. End If
    18. Dim Element As Object
    19. Dim Elements As Object
    20. Set Elements = strResponse.getElementsByClassName("col-xs-10")
    21. For Each Element In Elements
    22. Dim ElementHTML As HTMLDocument
    23. Set ElementHTML = New HTMLDocument
    24. ElementHTML.body.innerHTML = Element.innerHTML
    25. If Not strResponse.getElementsByClassName("open")(0) Is Nothing Then
    26. 'If Not strResponse.getElementsByClassName("openingHoursTable")(0) Is Nothing Then
    27. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 1).Value = Ortskreis
    28. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 2).Value = ElementHTML.getElementsByClassName("resultItem-CompanyName")(0).innerText
    29. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 3).Value = ElementHTML.getElementsByClassName("resultItem-Street")(0).innerText
    30. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 4).Value = ElementHTML.getElementsByClassName("resultItem-City")(0).innerText
    31. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = ElementHTML.getElementsByClassName("openingHoursTable")(0).innerText
    32. Else
    33. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 1).Value = Ortskreis
    34. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 2).Value = "Kein Aldi in diesem PLZ"
    35. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 3).Value = "Kein Aldi in diesem PLZ"
    36. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 4).Value = "Kein Aldi in diesem PLZ"
    37. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 5).Value = "Kein Aldi in diesem PLZ"
    38. End If
    39. i = i + 1
    40. Next
    41. Next
    42. Set MyHttpRequest = Nothing
    43. Set ALDIHTML = Nothing
    44. Set srtResponse = Nothing
    45. Application.ScreenUpdating = True
    46. End Sub

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „fatony“ ()

    fatony schrieb:

    wie kann das sein, dass obwohl "resultItem-CompanyName" nicht verfügbar ist, vba es doch erkennt und es in die Tabelle einträgt.
    Vermutlich nicht bei allen Datensätzen.
    Ich bin nur durchgesteppt und habe gesehen, dass es im ersten Datensatz Nothing war.

    fatony schrieb:

    Worksheets("Aldi_Oeffnungszeiten").Cells(i, 2).Value = ElementHTML.getElementsByClassName("resultItem-CompanyName")(0).innerText
    Splitte das mal und analysiere jeweils.

    Visual Basic-Quellcode

    1. Set CompanyName = ElementHTML.getElementsByClassName("resultItem-CompanyName")
    2. If CompanyName Is Nothing Then
    3. Stop ' element gibt's nicht wie erwartet
    4. Else
    5. Worksheets("Aldi_Oeffnungszeiten").Cells(i, 2).Value = CompanyName(0).InnerText
    6. End If
    ggf.musst du sogar noch granularer testen.

    Nimm auch mal den Debugger zu Hilfe und untersuche die Datenstruktur von ElementHTML.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --