Prüfen, ob ein Element mit Python Selenium existiert

Lesezeit: 8 Minuten

Benutzeravatar von nonshatter
unzerbrechlich

Ich habe ein Problem; Ich verwende den Selenium (Firefox)-Webtreiber, um eine Webseite zu öffnen, auf einige Links zu klicken usw. und dann einen Screenshot aufzunehmen.

Mein Skript läuft gut über die CLI, aber wenn es über a Cron-Job es kommt nicht über den ersten find_element()-Test hinaus. Ich muss etwas Debug hinzufügen oder etwas, das mir hilft, herauszufinden, warum es fehlschlägt.

Grundsätzlich muss ich auf einen „Anmelden“-Anker klicken, bevor ich zur Anmeldeseite gehe. Das Konstrukt des Elements ist:

<a class="lnk" rel="nofollow" href="/login.jsp?destination=/secure/Dash.jspa">log in</a>

Ich benutze die find_element Per LINK_TEXT-Methode:

login = driver.find_element(By.LINK_TEXT, "log in").click()

A) Wie überprüfe ich, ob der Link tatsächlich von Python aufgenommen wird? Soll ich den Try/Catch-Block verwenden?

B) Gibt es eine bessere/zuverlässigere Möglichkeit, die Dom Element als durch LINK_TEXT? Bsp. ein jQuerykönnen Sie einen spezifischeren Selektor verwenden, $(‘a.lnk:contains(log in)’).do_something();


Ich habe das Hauptproblem gelöst und es war nur ein Fingerproblem. Ich habe das Skript mit falschen Parametern aufgerufen – ein einfacher Fehler.

Ich hätte noch gerne ein paar Hinweise, wie man prüfen kann, ob ein Element existiert. Außerdem ein Beispiel/Erklärung für implizite/explizite Waits anstelle eines beschissenen time.sleep()-Aufrufs.

  • Sie können Elemente auch per CSS-Locator oder xpath finden. Neigt dazu, weniger spröde zu sein als bei Textinhalten.

    – Silas Strahl

    5. März 2012 um 15:15 Uhr

  • Ich glaube, dass beide – die Verwendung von Inhaltstext und XPATH/CSS – eher anfällig für geringfügige Änderungen im Design als in der Anwendungslogik sind. Ein besserer Weg wäre, das Element nach einem von beiden zu finden id, class_name oder name.

    – Kshitij Saraogi

    3. Mai 2017 um 13:30 Uhr

Benutzeravatar von Alex Okrushko
Alex Okruschko

Für ein):

from selenium.common.exceptions import NoSuchElementException
def check_exists_by_xpath(xpath):
    try:
        webdriver.find_element_by_xpath(xpath)
    except NoSuchElementException:
        return False
    return True

Zu b): Darüber hinaus können Sie den XPath-Ausdruck als Standard in all Ihren Skripten verwenden und Funktionen wie oben erwähnt für den universellen Einsatz erstellen.

Ich empfehle zu verwenden CSS-Selektoren. Ich empfehle, “by id”, “by name” usw. nicht zu mischen/zu verwenden und stattdessen einen einzigen Ansatz zu verwenden.

  • Sie sollten auch object: browser = webdriver.Firefox() an Ihre benutzerdefinierte Funktion übergeben

    Benutzer2558887

    27. Juni 2014 um 14:08 Uhr

  • Generell bin ich selten auf HTML-Seiten gestoßen, die der Idee des einheitlichen Matchings entsprechen. Gibt es eine Möglichkeit, Mix-Matches der Locator-Methoden auf solchen Seiten zu umgehen?

    – Kshitij Saraogi

    3. Mai 2017 um 13:34 Uhr

  • @KshitijSaraogi Verstehe deine Frage nicht ganz. Wenn Sie daran festhalten, dass es unmöglich ist, nur “CSS-Selektoren” in Ihren Webdriver-Tests zu haben – es ist tatsächlich durchaus möglich. Genau das mache ich seit 6 Jahren.

    – Alex Okruschko

    5. Mai 2017 um 20:05 Uhr

  • @AlexOkrushko Aus welchen Gründen empfehlen Sie CSS-Selektoren über xpath?

    – BoZenKhaa

    13. März 2018 um 14:19 Uhr

  • @BoZenKhaa, mindestens 2 Gründe: Vertrautheit der Entwickler mit CSS-Selektoren, was zur Lesbarkeit des Codes beiträgt; xpath hatte eine schreckliche Leistung im IE.

    – Alex Okruschko

    16. März 2018 um 10:20 Uhr

Benutzeravatar von Brian Leishman
Brian Leishmann

Sie können anstelle eines einzelnen Elements eine Liste von Elementen abrufen. Eine leere Liste in Python ist falsch. Beispiel:

if driver.find_elements(By.CSS_SELECTOR, '#element'):
    print "Element exists!"

Sie können auch verwenden By.ID und By.NAMEaber das verwandelt Ihre ID oder Ihren Namen sowieso in einen CSS-Selektor. Quelle

  • Ist dies schneller als die obige Methode zur Behandlung von Ausnahmen?

    – Gal Bracha

    17. Februar 2017 um 10:41 Uhr

  • @GalBracha Gute Frage, ich gehe davon aus, dass es wahrscheinlich von der Version und Plattform abhängen würde. Wenn Ihnen der Geschwindigkeitsunterschied hier also so wichtig ist, würde ich empfehlen, ihn auf Ihrer Zielplattform zu testen, um die besten Ergebnisse zu erzielen. Hier muss jedoch auf Voroptimierungen hingewiesen werden, und die Lesbarkeit des Codes könnte in diesem Fall wichtiger sein als die vernachlässigbare Leistungsverbesserung

    – Brian Leishmann

    17. Februar 2017 um 14:00 Uhr

  • Die Form find-element (Singular) löst eine Ausnahme aus, wenn das Element nicht gefunden wird. Die Find-Elemente (Plural mit ‘s’) geben eine leere Liste zurück. Meiner bescheidenen Meinung nach sind alle anderen Beispiele, die try-catch verwenden, um zu sehen, ob ein Element existiert, ein schlechter Programmierstil. Try-Catch sollte nur verwendet werden, um unerwartete Situationen abzufangen. Wenn Sie glauben, dass das Element möglicherweise nicht existiert, sollte Ihr Code so geschrieben werden, dass er diese Situation handhabt.

    – Bill Worthington

    8. März 2021 um 14:37 Uhr

  • @BillWorthington stimme zu 100% zu. Ich bin kein Python-Entwickler, also weiß ich nicht, was hier normal ist, aber ich würde die Dinge nicht so in anderen Sprachen schreiben

    – Brian Leishmann

    8. März 2021 um 14:52 Uhr

  • @BrianLeishman Ich habe versucht darauf hinzuweisen, dass Ihr Beispiel der RICHTIGE Weg ist, es zu tun, und die ANDEREN Beispiele waren kein guter Programmierstil.

    – Bill Worthington

    9. März 2021 um 15:38 Uhr

Benutzeravatar von Sam Woods
Sam Woods

A) Ja. Der einfachste Weg, um zu überprüfen, ob ein Element existiert, ist ein einfacher Aufruf find_element in einem try/catch.

B) Ja, ich versuche aus zwei Gründen immer, Elemente ohne ihren Text zu identifizieren:

  1. der Text ändert sich eher und;
  2. Wenn es Ihnen wichtig ist, können Sie Ihre Tests nicht mit lokalisierten Builds ausführen.

Die Lösung ist entweder:

  1. Sie können XPath verwenden, um ein übergeordnetes oder übergeordnetes Element zu finden, das eine ID oder einen anderen eindeutigen Bezeichner hat, und dann sein untergeordnetes/nachkommendes Element finden, das mit oder übereinstimmt;
  2. Sie könnten eine ID oder einen Namen oder eine andere eindeutige Kennung für den Link selbst anfordern.

Verwenden Sie für die Folgefragen try/catch So können Sie feststellen, ob ein Element vorhanden ist oder nicht, und gute Beispiele für Wartezeiten finden Sie hier: http://seleniumhq.org/docs/04_webdriver_advanced.html

  • Eine Verwendung, die ich zum Suchen von Text habe, besteht darin, zu sehen, ob eine erfolgreiche/nicht erfolgreiche Flash-Nachricht angezeigt wird. Nicht sicher, ob es einen besseren Weg gibt, es zu tun?

    – Rob Grant

    6. Oktober 2015 um 14:34 Uhr

  • Das sind absolut gute Gründe, die Auswahl per Text zu vermeiden

    – Kevlarr

    11. Januar 2018 um 16:30 Uhr

  • Dies war hilfreich, beachten Sie, dass Sie jetzt is_displayed() verwenden können: selenium.dev/documentation/webdriver/elements/information

    – Raul

    27. April um 9:10 Uhr

  • Der Link ist (effektiv) unterbrochen. Es leitet auf eine generische Seite weiter.

    – Peter Mortensen

    11. November um 7:02 Uhr

  • @Raoul: Würde das nicht auf das Problem einer ausgelösten Ausnahme stoßen?

    – Peter Mortensen

    11. November um 7:56 Uhr

Benutzeravatar von Super Mario
Super Mario

Eine Lösung ohne Try&Catch und ohne Neuimporte:

if len(driver.find_elements_by_id('blah')) > 0: # Pay attention: find_element*s*
    driver.find_element_by_id('blah').click # Pay attention: find_element

Benutzeravatar von vmk
vmk

Dasselbe wie Brian, aber ergänzen Sie dies Antwort von tstempko:

Ich habe es versucht und es funktioniert schnell:

driver.implicitly_wait(0)

if driver.find_element_by_id("show_reflist"):
    driver.find_element_by_id("show_reflist").find_element_by_tag_name("img").click()

Danach stelle ich meinen Standardwert wieder her:

driver.implicitly_wait(30)

  • Jawohl! Wenn Sie wissen, dass die Seite bereits geladen ist, möchten Sie nicht 30 Sekunden warten, um Ihre “existiert nicht”-Rückgabe zu erhalten. das kehrt sofort zurück, genau das, was ich brauchte.

    – welch

    11. Mai 2018 um 6:32 Uhr


  • Würde das nicht eine Ausnahme auslösen, wenn etwas nicht existiert (der springende Punkt dieser Frage)? Und damit nicht wirklich funktionieren?

    – Peter Mortensen

    10. November um 4:09 Uhr


  • OK, das OP hat das Gebäude verlassen: “Zuletzt gesehen vor mehr als 1 Jahr”. Vielleicht kann sich noch jemand melden?

    – Peter Mortensen

    11. November um 7:19 Uhr

  • Aus Bill Worthingtons Kommentar: “Die Form find-element (singular) löst eine Ausnahme aus, wenn das Element nicht gefunden wird.”. Werden driver.implicitly_wait(0) verhindern, dass die Ausnahme ausgelöst wird?

    – Peter Mortensen

    11. November um 7:47 Uhr


Du könntest es auch prägnanter machen mit

driver.find_element_by_id("some_id").size != 0

  • Jawohl! Wenn Sie wissen, dass die Seite bereits geladen ist, möchten Sie nicht 30 Sekunden warten, um Ihre “existiert nicht”-Rückgabe zu erhalten. das kehrt sofort zurück, genau das, was ich brauchte.

    – welch

    11. Mai 2018 um 6:32 Uhr


  • Würde das nicht eine Ausnahme auslösen, wenn etwas nicht existiert (der springende Punkt dieser Frage)? Und damit nicht wirklich funktionieren?

    – Peter Mortensen

    10. November um 4:09 Uhr


  • OK, das OP hat das Gebäude verlassen: “Zuletzt gesehen vor mehr als 1 Jahr”. Vielleicht kann sich noch jemand melden?

    – Peter Mortensen

    11. November um 7:19 Uhr

  • Aus Bill Worthingtons Kommentar: “Die Form find-element (singular) löst eine Ausnahme aus, wenn das Element nicht gefunden wird.”. Werden driver.implicitly_wait(0) verhindern, dass die Ausnahme ausgelöst wird?

    – Peter Mortensen

    11. November um 7:47 Uhr


Benutzeravatar von Peter Mortensen
Peter Mortensen

driver.find_element_by_id("some_id").size() ist eine Klassenmethode.

Wir brauchen:

driver.find_element_by_id("some_id").size das ist ein Wörterbuch, also:

if driver.find_element_by_id("some_id").size['width'] != 0:
   print 'button exist'

  • Dies ist nicht immer richtig, die Breite kann Null sein, wenn das Element auch vorhanden ist. el = driver.find_element_by_class_name(‘gNO89b’) el.size Dies ist ein gültiges Element auf der Google-Suchseite, aber die Breite ist 0

    – Codelord

    6. Oktober 2020 um 16:23 Uhr

  • Ich glaube nicht, dass das funktionieren wird. find_element_by_id() löst wahrscheinlich eine Ausnahme aus, wenn das Element nicht existiert (der springende Punkt dieser Frage).

    – Peter Mortensen

    11. November um 7:23 Uhr

  • Aus Bill Worthingtons Kommentar: “Die Form find-element (singular) löst eine Ausnahme aus, wenn das Element nicht gefunden wird.”

    – Peter Mortensen

    11. November um 7:49 Uhr

1433750cookie-checkPrüfen, ob ein Element mit Python Selenium existiert

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy