Ich habe ein Problem - ich verwende den Selenium (Firefox) Web-Treiber, um eine Webseite zu öffnen, auf ein paar Links zu klicken usw. und dann einen Screenshot aufzunehmen.
Mein Skript läuft gut über die CLI, aber wenn es über einen Cronjob ausgeführt wird, kommt es nicht über den ersten find_element () -Test hinaus. Ich muss ein Debug hinzufügen oder etwas, um herauszufinden, warum es fehlschlägt.
Grundsätzlich muss ich auf einen Anmeldeanker 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 verwende die Methode find_element By LINK_TEXT:
login = driver.find_element(By.LINK_TEXT, "log in").click()
Ich bin ein bisschen ein Python Noob, also kämpfe ich ein bisschen mit der Sprache ...
A) Wie überprüfe ich, ob der Link tatsächlich von Python aufgenommen wird? Soll ich try / catch block verwenden?
B) Gibt es eine bessere / zuverlässigere Möglichkeit, das DOM-Element zu lokalisieren als mit LINK_TEXT? In JQuery können Sie beispielsweise einen spezifischeren Selektor $ ('a.lnk: enthält (Login)') verwenden. Do_something ();
Ich habe das Hauptproblem gelöst und es war nur ein Fingerproblem - ich habe das Skript mit falschen Parametern aufgerufen - Einfacher Fehler.
Ich möchte noch einige Hinweise, wie Sie überprüfen können, ob ein Element vorhanden ist. Auch ein Beispiel / eine Erklärung für implizite / explizite Wartezeiten anstelle eines beschissenen Aufrufs von time.sleep ().
Prost, ns
id
,class_name
odername
.Antworten:
A) Ja. Der einfachste Weg , um zu überprüfen , ob ein Element vorhanden ist, rufen Sie einfach im
find_element
Innern eintry/catch
.B) Ja, ich versuche aus zwei Gründen immer, Elemente zu identifizieren, ohne ihren Text zu verwenden:
Lösung entweder:
Bei den folgenden Fragen können Sie anhand von
try/catch
feststellen, ob ein Element vorhanden ist oder nicht. Gute Beispiele für Wartezeiten finden Sie hier: http://seleniumhq.org/docs/04_webdriver_advanced.htmlquelle
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
b)
Verwenden Sie xpath - das zuverlässigste.Darüber hinaus können Sie den xpath in all Ihren Skripten als Standard verwenden und Funktionen wie oben erwähnt für den universellen Gebrauch erstellen.UPDATE : Ich habe die erste Antwort vor über 4 Jahren geschrieben und damals dachte ich, xpath wäre die beste Option. Jetzt empfehle ich die Verwendung von CSS-Selektoren . Ich empfehle immer noch, "nach ID", "nach Name" usw. nicht zu mischen / zu verwenden und stattdessen einen einzigen Ansatz zu verwenden.
quelle
Keine der angebotenen Lösungen schien mir am einfachsten zu sein, daher möchte ich meinen eigenen Weg hinzufügen.
Grundsätzlich erhalten Sie die Liste der Elemente anstelle nur des Elements und zählen dann die Ergebnisse. Wenn es Null ist, existiert es nicht. Beispiel:
if driver.find_elements_by_css_selector('#element'): print "Element exists"
Beachten Sie das "s"
find_elements_by_css_selector
, um sicherzustellen, dass es zählbar ist.BEARBEITEN : Ich habe
len(
die Liste überprüft , aber ich habe kürzlich erfahren, dass eine leere Liste falsch ist, sodass Sie die Länge der Liste überhaupt nicht ermitteln müssen, um noch einfacheren Code zu erhalten.Eine andere Antwort besagt, dass die Verwendung von xpath zuverlässiger ist, was einfach nicht stimmt. Siehe Was ist der Unterschied zwischen CSS-Selektor und Xpath? Was ist besser (je nach Leistung und für Cross-Browser-Tests)?
quelle
find_elements_by_id
. Übrigensfind_element_by_xpath
wirft ein Fehler, wenn das Element nicht verfügbar istfind_element_by_xpath
wirft einen Fehler aus, wenn es kein Element finden kann, weil es nicht die Pluralversion der Funktion istfind_elements_by_css_selector
egal, ob ein Eingabeelement vorhanden isttype="hidden"
, da ich es genau dafür in einem meiner Anwendungsfälle verwendeLö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
quelle
e = driver.find_elements_by_id('blah') if e: e[0].click
you're finding twice
.if len(driver.find_elements_by_id('blah')): #do something
sollte auch das Gleiche tun. (> 0
) ist nicht erforderlich.Das gleiche wie Brian, aber fügen Sie dieser Antwort von tstempko hinzu:
/sqa/3481/quicker-way-to-assert-that-an-element-does-not-exist
Also habe ich 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)
quelle
Sie können es auch präziser verwenden
driver.find_element_by_id("some_id").size != 0
quelle
driver.find_element_by_id("some_id").size()
ist Klassenmethode.Was wir brauchen ist:
driver.find_element_by_id("some_id").size
Welches ist Wörterbuch so:if driver.find_element_by_id("some_id").size['width'] != 0 : print 'button exist'
quelle
Sie können is_displayed () wie unten verwenden
res = driver.find_element_by_id("some_id").is_displayed() assert res, 'element not displayed!'
quelle