Webdriver xPath iFrames usw.

  • Hallo ihr Experten,

    ich hab mal wieder ein Problem.

    Hab versucht mit ChroPath und SelectorsHub den xPath auszulesen.

    Komme da nicht weiter.

    Mal läuft das Script durch, meistens bleibt es irgendwo stehen.

    - vielleicht sind die xPath falsch oder es liegt an den iframes oder svg.

    - im headless Mode läuft es überhaupt nicht.

    - gibt es eine möglichkeit das besser abzusichern - Hatte schon eine While 1 Schleife um jeden Punkt gebaut.
    - kann man den Zugriff schneller machen - oder läßt Mydrive nicht mehr zu.

    Vielleicht kann mal einer drüber gucken und mir entsprechende Tips geben.

    Danke!

    Viele Grüße

    Werner


    Einmal editiert, zuletzt von SOLVE-SMART (23. Januar 2023 um 20:31)

  • Oh Windi (Werner),


    ich habe keine Ahnung wo ich ansetzen soll. Ich weiß erstens schon mal nicht von was du sprichst und zweites fehlt auch jede Testmöglichkeit um nachzuvollziehen was du vor hast bzw. was geht und was nicht.

    Generell sehen die XPath strings ganz okay aus, doch ohne die Webseite bzw. ohne einen Auszug aus dem DOM kann ich absolut nicht weiter helfen.

    Du beschreibst dein Problem irgendwie so, als hätten wir da bereits in der Vergangenheit den Kontext von dir bekommen => also hast du schon mal irgendwo hier, in 'nem anderen Thread, das Thema erläutert oder woher sollen wir wissen was genau du vor hast? Vielleicht weiß es nur ich nicht und dem einen oder anderen ist es bekannt, keine Ahnung!

    Ich würde dir wirklich gerne helfen und beim Thema WebDriver sehe ich mich auch dazu in der Lage, doch ich brauche dazu deine Unterstützung.

    • Ist dies dein komplettes Skript/Programm?
    • Können wir dies nachvollziehen oder braucht es irgendwelche TomTom Software etc.?
    • Kannst du Screenshots von der Webseite und vom DOM, wo du mit SelectorsHub den XPath eingibst um deine Elemente zu finden, machen?
    • Kannst du des Weiteren auch nochmal beschreiben was du tun möchtest?
    • Kannst du bitte auf deine vier Punkte (deine vier Stichpunkte "- ....") nochmal etwas genauer eingehen?

    Danke für deine Mühen 🤝 . Ich für meinen Teil kann sagen, sobald ich weiß was los ist und die nötigen Infos habe, kann ich dir mit Sicherheit helfen. Einige andere hier sicherlich auch 😀 .

    Viele Grüße
    Sven

  • Hallo Sven,

    danke für deine Meldung.

    Kannst du Screenshots von der Webseite und vom DOM, wo du mit SelectorsHub den XPath eingibst um deine Elemente zu finden, machen?

    AutoIt
    ; TomTom MyDrive Link                                                                                          
    Global $URLMyDr = ("https://mydrive.tomtom.com/de_de/#mode=viewport+viewport" _
                       & "=49.9071,7.8184,13,0,-0+ver=3")

    Die Webseite ist doch vorhanden.

    Mein Vorhaben:

    Es soll nach dem einloggen, in der Reihenfolge wie im Scribt, die einzelnen Buttons gecklickt bzw. Einträge gemacht werden.

    Im Original kommt noch eine Schleife drum, um diverse Adressen rein zu schieben.

    Wie ich schon geschrieben habe, funktioniert es manchmal und meisten aber nicht.

    Ich vermute es liegt an den xPath oder iframes

    Es sind auch nicht immer die selben die nicht funktionieren.

    Ich habe es schon mit Sleep von 100 bis 1500 probiert.

    Habe auch um jeden Punkt eine While 1 Schleife gemacht und Sleep jedes Mal um 100 erhöht.

    Lass mich wissen was du noch alles brauchst.

    Ich weiß das du dich mit dem Webdriver auskennst.

    Viele Grüße

    Werner

    Einmal editiert, zuletzt von SOLVE-SMART (23. Januar 2023 um 20:31)

  • Ich schaue es mir mal in Ruhe an Werner. Ich melde mich 😀 .

    Nur eine Anmerkung schon mal:
    Entweder der XPath stimmt oder eben nicht. Du schreibst es geht manchmal, dass heißt am XPath liegt es nicht. Denn wenn dieser nicht stimmt, dann bekommst du nicht das Element zurück, was du haben möchtest oder mit dem du interagieren möchtest. Somit bekommst du nicht den Text des Elements oder Klickst nicht auf das richtige Element oder was auch immer du damit tun willst.

    Es scheint ein Zeitverhalten zu sein, welches angepasst werden muss (aber nicht mit Sleep() oder so). Dies ist jedoch nur eine Vermutung auf Grund deiner Beschreibung bisher.

    Ich melde mich.

    Viele Grüße
    Sven

  • Danke!

    Reiß dir kein Bein aus ich kann warten. :)

    Wenn du nicht weiter kommst kann ich dir auch Test login Daten senden.

    Gibt es da eine geschützte Möglichkeit im Forum.

    Viele Grüße

    Werner

  • Du kannst einfach eine Konversation mit mir starten. Also private Nachricht schreiben. Siehe Link.

    Viele Grüße
    Sven

  • Hallo Werner ( Windi),

    wie angekündigt "ich melde mich" hier ein Zwischenstand:
    Ich konnte den Ablauf deines Skripts, mit den Login-Daten des Test-Accounts1, erfolgreich nachvollziehen und testen 👍 . Nun folgen ein paar Änderungen am Verhalten des Skriptes bzgl. Warteverhalten des Browsers/der Webseite.

    Der Ablauf, die XPath-Strings und auch das Vorgehen ist in Ordnung gewesen Werner, nur das Warteverhalten nicht robust genug wenn du die Aktionen in einer Schleife ausführen möchtest. Daher brach es sicherlich immer wieder mal ab. Ich versuche die Funktionen so anzulegen, dass du gut damit umgehen können solltest. Ob der headless mode funktioniert kann ich dir nach der Optimierung/Anpassung sagen. Ich versuche das Ganze auch mit Chrome und Firefox zu machen, damit du ggf. die Auswahl hast (derzeit nutzt du ja Firefox).

    Also, ich melde mich bald2 (ggf. heute noch) mit ersten Ergebnissen 😀 .

    Viele Grüße

    Sven

    1 Hinweis für die anderen: diese Daten hat mir Werner geschickt

    2 Voraussichtlich am Dienstag

  • Hi Windi,

    zu einer deiner Fragen hier noch kurz:

    Nochwas!

    ist Fehler abfrage so richtig.

    Nein ist sie nicht Werner. Du prüfst ob @error gleich "Erfolg" ist:

    AutoIt
    Local $sButton = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, $xPath)
    If @error = $_WD_ERROR_Success Then
        ...

    jedoch musst du stattdessen auf ungleich püfen:

    AutoIt
    Local $sButton = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, $xPath)
    If @error <> $_WD_ERROR_Success Then
        MsgBox(16, 'Error', 'Fehler ...')
        Exit
    EndIf

    Denn $_WD_ERROR_Success ist in wd_core.au3 mit 0 initialisiert. Daher bitte überprüfen ob @error ungleich 0 ist.

    In dem Beispielprogramm von mir wird dies aber sowieso etwas anders aussehen. Bis bald.

    Viele Grüße
    Sven

  • Hallo Sven,

    vielen Dank für deine Mühe.

    Ich hatte das Thema schon einmal 2021 angestoßen.

    Link: Webdriver Button drücken

    Damals hatte mir Dan, vom englischen Forum geantwortet.

    Von ihm habe ich auch die Fehlerabfrage übernommen.

    Einmal editiert, zuletzt von SOLVE-SMART (23. Januar 2023 um 20:31)

  • Hallo Werner,

    Prinzipiell mache ich das auch immer so, wie oben angegeben.

    Hier mal ein Beispiel:

    AutoIt
    $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "/html/body/div[1]/aside[1]/div[2]/div/div[2]/div/div/form/button")
    ;_WD_HighlightElement($sSession, $sElement, 3)
    
    If @error = $_WD_ERROR_Success Then
    _WD_ElementAction($sSession, $sElement, 'click')
    Sleep(500)
    
    ;oder so
    $sElement_login_btn = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, '//*[@id="btnLogin"]')

    Gruß gmmg

  • Hi Windi, hi gmmg,

    ich glaube wir reden zwar vom Gleichen, jedoch mit einer unterschiedlichen Idee dahinter 😅 .

    Punkt (1)

    [...] Damals hatte mir Dan, vom englischen Forum geantwortet.

    Von ihm habe ich auch die Fehlerabfrage übernommen. [...]

    [...] Prinzipiell mache ich das auch immer so, wie oben angegeben.

    AutoIt
    $sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "/html/body/div[1]/aside[1]/div[2]/div/div[2]/div/div/form/button")
    ;_WD_HighlightElement($sSession, $sElement, 3)
    
    If @error = $_WD_ERROR_Success Then
    _WD_ElementAction($sSession, $sElement, 'click')
    Sleep(500)
    
    ;oder so
    $sElement_login_btn = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, '//*[@id="btnLogin"]')

    [...] Gruß gmmg

    Beides okay, in Ordnung und richtig 👍 . Allerdings ist eure Herangehensweise, wenn ich das richtig bewerte diese, dass ihr nur wenn kein Fehler auftritt den nächsten Schritt tun wollt. Also bei @error = $_ED_ERROR_Success dann in die nächste Aktion geht.

    Mein Hinweis bezog sich darauf, dass ich genau andersherum auswerten möchte und beim Auftritt von einem Fehler aus dem Programm aussteigen möchte (oder einfach nur eine MsgBox() oder einen Hinweis auf der Konsole ConsoleWrite() ausgeben möchte), aber eben nicht weiter im Kontext machen möchte. Vereinfacht gesagt vertausche ich die if-else Bedingungen, mehr nicht (IF "Fehler", DANN Return ELSE "weiter im Kontext"). Dies entspricht dem "REP (return early pattern)". Ist jedoch nicht weiter wichtig (dient aber der Erklärung).

    gmmg macht dies sicher richtig und du auch Werner, allerdings in dem konkreten Beispiel deines Skriptes, macht es keinen Sinn meiner Meinung nach. Du weißt das es "irgendwo" instabil ist und eine Aktion nicht korrekt ausgeführt wird, weißt jedoch auf Grund des Logs in der Konsole auch nicht genau welche Stelle es ist. Daher die Variante mit "sobald fehlgeschlagen, aussteigen, den letzten Log Eintrag anschauen und "aha, dort ist es", Ende, finito 😅 .

    Ich denke ich kann morgen das Skript und die Abhängigkeiten zur Verfügung stellen Werner, dann könnt ihr sehr gern nochmal etwas dazu sagen: ob gut oder nicht, bin absolut offen für Verbesserungen 😇 .


    Punkt (2)

    [...] Dan schrieb dass es an den iFrames hängt.

    Bei meine Orte z. B. [...]

    Ja, konkret ist die Seite in der Automatisierung etwas instabil, weil sie mehrerer iframes einbindet und mit _WD_FrameEnter() und _WD_FrameLeave() gearbeitet werden muss.

    [...] Weder ChroPath noch SelectorsHub findet da was vernünftiges.

    Hab dann solange rumprobiert bis ich auf den xPath kam.

    Aber wie du schon geschrieben hast, es läuft nicht stabil. [...]

    Des Weiteren nutzt die Webseite Animationen, mit denen der WebDriver nicht immer ohne Zutun umgehen kann. Dies erzeugt das Zeitverhaltenproblem. Nun kann man dies durch genügend Wartezeiten (keine eigenen Sleeps Sleep() sondern über _WaitFor() bzw. _WD_WaitElement()) beheben und in Kauf nehmen, dass das Skript nicht gerade das Schnellste ist (so löse ich das übrigens auch bei deinem Skript/deinem Fall Windi) oder man macht es ganz genau und robust in dem man mit JavaScript Events arbeitet und wirklich wartet bis eine gewissen Animation abgeschlossen ist. Diese Variante ist deutlich aufwändiger und zumindest für mich, nur im beruflichen Kontext relevant.

    Naja, Verbesserungspotenzial gibt es immer 😅 . Melde mich morgen wieder.

    Viele Grüße
    Sven

  • Hallo,

    ihr habt beide recht!

    Ich hatte es einmal so versucht:

    Wollte ihn damit Überlisten :):):):)

    Ich denke in dem Fall, war mein Ansatz richtig.

    Lief manchmal auch ins unendliche und das bei jedem xPath. :cursing:

    Bin mal gespannt, wie das noch ausgeht!

    Egal wie, trotzdem Danke an alle Beteiligten.

    Gruß Werner

    Einmal editiert, zuletzt von SOLVE-SMART (23. Januar 2023 um 20:30)

  • Hallo erneut Windi ,

    kannst du mir bitte mal ein Beispiel senden oder zumindest einen Auszug aus deiner Adresstabelle oder Adressliste geben?
    Also ich nehme folgendes an:

    • Neuen Ort hinzufügen
    • Adresse und Name eingeben
    • erste vorgeschlagene Adresse auswählen
    • Fertig button klicken

    läuft alles in einer Schleife, richtig? Also so würde ich es tun. Doch du kennst deinen fachlichen Ablauf und Kontext besser 😅 .

    Im Moment habe ich zum Test einfach nur ein Array (eine Dummy Tabelle) erstellt, die in der Schleife durchgearbeitet wird. Diese besteht einfach aus Adresse und Name (was ja optional ist):

    AutoIt
    Local $aTableOfAddresses[][2] = _
        [ _
            ['Westfälische Str. 52 57368 Lennestadt', 'Landhotel'], _
            ['Landsberger Straße 10 80339 München',   'Test München'], _
            ['Hermannstrasse 9 90439 Nürnberg',       'Test Nürnberg'], _
            ['Pohlstrasse 67 10785 Berlin',           'Test Berlin'], _
            ['Aachener Straße 300 50933 Köln',        'Test Köln'] _
        ]

    Wenn deine CSV deutlich abweicht, dann müsste ich das in meinem Test berücksichtigen, darum frage ich.

    • Abgesehen davon läuft es im Chrome bereits robust durch, auch im headless Modus. Aber Firefox muss ich noch fertig testen. Dann bekommst du meinen Vorschlag.
    • Doch zunächst brauche ich bitte eine Angabe von dir wie viele Adressen auf einmal eingepflegt werden sollen (etwa) und wie die CSV bzw. deine Daten aussehen (auch nur grob).

    Danke dir Werner 🤝 .

    Viele Grüße
    Sven

  • Hallo Sven

    Die Daten kommen aus einen 2D Array mit 2 Spalten.

    Code
    Row   Col 0                             Col 1
    #0    01.) Mustermann Max und Hilde     11111 Musterhausen Musterstr. 1-5

    In der Regel sind es ca. 30-40 Adressen.

    Es können auch mal 100 sein, wenn Ware vorausgeschickt wird mit Spedition und dann verteilt wird (ist aber eher selten).

    Wenn du wegen der Schnelligkeit fragst, ist nicht ganz so wichtig.

    Hauptsache stabil.

    Viele Grüße

    Werner

  • Alles klar Werner, dann ist mein Array oben also genau vertauscht? Erst Name, dann Adresse, okay - passe ich noch an.
    Die Angabe das es bis zu 100 Adressen sein können ist gut, dann Teste ich mal mit 75 und schaue wie es sich verhält.

    Viele Grüße
    Sven

  • Hi Windi (Werner) 👋 ,

    hier nun mein Vorschlag, für deine Website Automatisierung/Steuerung mydrive.tomtom.com.

    • Die wichtigsten Stellen habe ich kommentiert.
      • Ich hoffe das reicht dir, ansonsten sind die Funktionen und Variablen treffend benannt.
      • Frage bitte gerne nach, wenn dir irgendwas unklar sein sollte 🤝 .
    • $sUsername und $sPassword sind nicht die Richtigen1.
    • Testdaten müssen mit deinen Echtdaten noch ausgetauscht werden.
    • Fehlerbehandlung ist nur minimal vorhanden, sehe den Bedarf tatsächlich eher gering.
      • Auch hierbei kann der Ablauf noch ausgebaut/robuster gemacht werden (wirst du sehen ob du da mehr brauchst oder nicht).
    • Derzeit ist die Ausführung der Klicks mit einer Verzögerung von einer Sekunde (1000ms) angelegt, da ansonsten die Animationen der Webseite die robuste Ausführung verhindern könnte.
      💡 500ms reicht auch, doch im headless ($bIsHeadlessMode) Modus empfehle ich bei dieser Seite 1000ms.
    • Randnotiz: Im kommenden WebDriver Tutorial wird die Strukturierung nochmal anders sein.

    Das Skript allein, ist so nicht lauffähig. Alle Abhängigkeiten2, welche benötigt werden, inklusive des Main.au3 Skriptes können hier heruntergeladen werden3.


    Viel Erfolg Werner damit 😀 .


    Viele Grüße
    Sven

    1 Als Hinweis für alle die, die dies komplett nachstellen wollen, bitte an Werner direkt wenden.

    2 Der benötigte WebDriver (entweder Chrome oder Firefox), wird via "_WD_UpdateDriver()" heruntergeladen. Daher ist dieser nicht im verlinktem Verzeichnis vorhanden.

    3 Achtung, auch wieder fake Login-Daten.

  • Hallo Sven,

    ich weiß gar nicht wie ich dir danken soll.

    Ich werde es morgen mal einbauen.

    werde mich dann mit Sicherheit nochmal melden.

    Vielen Lieben Dank

    bis morgen

    Werner

    Einmal editiert, zuletzt von Windi (25. Januar 2023 um 00:26) aus folgendem Grund: Ich bin sprachlos....... So sauber ist es noch nie durchgelaufen..... Danke, danke, danke