Python - Selenium WebDriver - 检查元素存在

时间:2012-03-05 13:00:32

标签: python selenium webdriver

我遇到了问题 - 我正在使用selenium(firefox)网络驱动程序打开网页,点击几个链接等,然后捕获截图。

我的脚本在CLI中运行良好,但是当通过cronjob运行时,它没有超过第一个find_element()测试。我需要添加一些调试,或者某些东西来帮助我弄清楚它失败的原因。

基本上,我必须在进入登录页面之前单击“登录”锚点。元素的构造是:

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

我正在使用find_element By LINK_TEXT方法:

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

我有点像Python Noob,所以我正在与语言进行斗争......

A)如何检查链接是否实际被python拾取?我应该使用try / catch块吗?

B)找到DOM元素比LINK_TEXT有更好/更可靠的方法吗?例如。在JQuery中,您可以使用更具体的选择器$('a.lnk:contains(登录)')。do_something();


我已经解决了主要问题,这只是手指麻烦 - 我用不正确的参数调用脚本 - 简单的错误。

我仍然喜欢一些关于如何检查元素是否存在的指针。另外,隐式/显式Waits的示例/解释而不是使用糟糕的time.sleep()调用。

干杯,ns

9 个答案:

答案 0 :(得分:76)

A)

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)使用xpath - 最可靠。此外,您可以在所有脚本中将xpath作为标准,并创建上述提及的功能以供普遍使用。

更新:我写了4年前的初步答案,当时我认为xpath是最好的选择。现在我建议使用 css选择器。我仍然建议不要混合/使用“by id”,“by name”等,而是使用一种方法。

答案 1 :(得分:44)

A)是的。检查元素是否存在的最简单方法是在find_element内调用try/catch

B)是的,我总是试图识别元素而不使用他们的文本有两个原因:

  1. 文字更有可能改变;
  2. 如果它对您很重要,您将无法针对本地化版本运行测试。
  3. 解决方案:

    1. 您可以使用xpath查找具有ID或其他唯一标识符的父元素或祖先元素,然后找到匹配的子元素/后代;
    2. 您可以为链接本身请求ID或名称或其他唯一标识符。
    3. 对于后续问题,使用try/catch可以判断元素是否存在,并且可以在此处找到好的等待示例:http://seleniumhq.org/docs/04_webdriver_advanced.html

答案 2 :(得分:40)

所提供的解决方案对我来说都不是最容易的,所以我想自己添加。

基本上,您获取元素列表而不仅仅是元素,然后计算结果;如果它为零,那么它就不存在了。示例:

<select>

注意&#34; s&#34;在if driver.find_elements_by_css_selector('#element'): print "Element exists" 中确保它可以计算。

编辑:我正在检查列表的find_elements_by_css_selector,但我最近得知空列表是假的,所以你不需要知道列表的长度列表,留下更简单的代码。

另外,另一个答案说使用xpath更可靠,但事实并非如此。见What is the difference between css-selector & Xpath? which is better(according to performance & for cross browser testing)?

答案 3 :(得分:2)

无需try&catch且无需新导入的解决方案:

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

答案 4 :(得分:1)

和Brian一样,但是从tstempko添加这个答案:

https://sqa.stackexchange.com/questions/3481/quicker-way-to-assert-that-an-element-does-not-exist

所以我尝试了,它很快就能运作:

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()

之后我恢复默认值

driver.implicitly_wait(30)

答案 5 :(得分:1)

您可以像下面那样使用is_displayed()

res = driver.find_element_by_id("some_id").is_displayed()
assert res, 'element not displayed!'

答案 6 :(得分:0)

您还可以使用以下内容更简洁地完成

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

答案 7 :(得分:0)

driver.find_element_by_id("some_id").size()是类方法。

我们需要的是:

driver.find_element_by_id("some_id").size这是字典,所以:

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

答案 8 :(得分:0)

如果数组长度等于0元素不存在,您可以通过可用方法查找元素并检查响应数组长度。

element_exist = False if len(driver.find_elements_by_css_selector('div.eiCW-')) > 0 else True