J'ai un problème - j'utilise le pilote Web Selenium (firefox) pour ouvrir une page Web, cliquez sur quelques liens, etc., puis faites une capture d'écran.
Mon script fonctionne correctement à partir de la CLI, mais lorsqu'il est exécuté via un cronjob, il ne dépasse pas le premier test find_element (). J'ai besoin d'ajouter un débogage, ou quelque chose pour m'aider à comprendre pourquoi il échoue.
Fondamentalement, je dois cliquer sur une ancre de "connexion" avant de me rendre à la page de connexion. La construction de l'élément est:
<a class="lnk" rel="nofollow" href="/login.jsp?destination=/secure/Dash.jspa">log in</a>
J'utilise la méthode find_element By LINK_TEXT:
login = driver.find_element(By.LINK_TEXT, "log in").click()
Je suis un peu un Python Noob, alors je me bats un peu avec la langue ...
A) Comment puis-je vérifier que le lien est effectivement capté par Python? Devrais-je utiliser try/catch block?
B) Existe-t-il un moyen meilleur/plus fiable de localiser l'élément DOM que par LINK_TEXT? Par exemple. Dans JQuery, vous pouvez utiliser un sélecteur plus spécifique, $ ('a.lnk: contient (se connecter)'). Do_something ();
J'ai résolu le problème principal et c'était juste un problème de doigt - J'appelais le script avec des paramètres incorrects - Simple erreur.
Je voudrais quand même des indications sur la manière de vérifier si un élément existe. En outre, un exemple/explication de Waits implicite/explicite au lieu d’utiliser un appel crappy time.sleep ().
À la vôtre, ns
A) oui Le moyen le plus simple de vérifier l’existence d’un élément consiste à appeler simplement find_element
dans un try/catch
.
B) Oui, j'essaie toujours d'identifier des éléments sans utiliser leur texte pour deux raisons:
solution soit:
Pour les questions suivantes, utilisez try/catch
pour savoir si un élément existe ou non, et de bons exemples d’attente peuvent être trouvés ici: http://seleniumhq.org/docs/04_webdriver_advanced.html
une)
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) utilisez xpath - le plus fiable. De plus, vous pouvez prendre le xpath en tant que norme dans tous vos scripts et créer les fonctions décrites ci-dessus pour une utilisation universelle.
UPDATE: J'ai écrit la réponse initiale il y a plus de 4 ans et, à l'époque, je pensais que xpath serait la meilleure option. Maintenant, je recommande d’utiliser les sélecteurs css . Je recommande toujours de ne pas mélanger/utiliser "par identifiant", "par nom", etc., et d’utiliser une seule approche à la place.
Aucune des solutions fournies ne m'a semblé la plus facile, alors j'aimerais ajouter ma propre manière.
Fondamentalement, vous obtenez la liste des éléments au lieu de simplement l'élément, puis vous comptez les résultats; si c'est zéro, alors ça n'existe pas. Exemple:
if driver.find_elements_by_css_selector('#element'):
print "Element exists"
Notez le "s" dans find_elements_by_css_selector
pour vous assurer qu'il peut être comptabilisé.
EDIT: Je vérifiais le len(
de la liste, mais j'ai récemment appris qu'une liste vide est falsey. Vous n'avez donc pas besoin de connaître la longueur de la liste, ce qui vous laisse un code encore plus simple.
En outre, une autre réponse indique que l'utilisation de xpath est plus fiable, ce qui n'est tout simplement pas vrai. Voir Quelle est la différence entre css-selector et Xpath? quel est le meilleur (en fonction des performances et des tests sur plusieurs navigateurs)?
Solution sans try & catch et sans nouvelles importations:
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
Identique à Brian, mais ajoutez à cette réponse de tstempko:
https://sqa.stackexchange.com/questions/3481/quicker-way-to-assert-that-an-element-does-not-exist
Alors j'ai essayé et ça marche vite:
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()
après cela, je restaure ma valeur par défaut
driver.implicitly_wait(30)
driver.find_element_by_id("some_id").size()
est une méthode de classe.
Ce dont nous avons besoin, c'est:
driver.find_element_by_id("some_id").size
qui est un dictionnaire pour:
if driver.find_element_by_id("some_id").size['width'] != 0 :
print 'button exist'
Vous pouvez également le faire de manière plus concise en utilisant
driver.find_element_by_id("some_id").size() != 0