使用Python Selenium检查元素是否存在

使用Python Selenium检查元素是否存在,python,html,selenium,webdriver,Python,Html,Selenium,Webdriver,我有一个问题-我正在使用selenium(firefox)web驱动程序打开一个网页,单击一些链接等,然后捕获一个屏幕截图 我的脚本在CLI中运行良好,但当通过cronjob运行时,它没有通过第一个find_element()测试。我需要添加一些调试,或者帮助我找出它失败的原因 基本上,在进入登录页面之前,我必须单击“登录”锚。该元素的构造为: <a class="lnk" rel="nofollow" href="/login.jsp?destination=/secure/Dash.j

我有一个问题-我正在使用selenium(firefox)web驱动程序打开一个网页,单击一些链接等,然后捕获一个屏幕截图

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

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

<a class="lnk" rel="nofollow" href="/login.jsp?destination=/secure/Dash.jspa">log in</a>
我是一个有点像Python的Noob,所以我正在和语言斗争一点

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

B) 有没有比通过LINK\u TEXT更好/更可靠的方法来定位DOM元素?例如,在JQuery中,您可以使用更具体的选择器$('a.lnk:contains(login)')


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

我仍然想要一些关于如何检查元素是否存在的指针。此外,还提供了隐式/显式等待的示例/解释,而不是使用糟糕的time.sleep()调用

干杯,是的。检查元素是否存在的最简单方法是在
try/catch
中调用
find\u element

B) 是的,我总是尝试在不使用文本的情况下识别元素,原因有二:

  • 文本更有可能发生更改和更改
  • 如果这对您很重要,您将无法对本地化的构建运行测试
  • 解决方案:

  • 您可以使用xpath查找具有ID或其他唯一标识符的父元素或祖先元素,然后查找与或匹配的子元素/子元素
  • 您可以为链接本身请求ID、名称或其他唯一标识符
  • 对于后续问题,使用
    try/catch
    可以判断元素是否存在,并且可以在此处找到等待的好例子:

    a)

    b) 使用最可靠的xpath。此外,您可以在所有脚本中使用xpath作为标准,并创建上述通用函数


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

    提供的解决方案中没有一种对我来说是最简单的,因此我想添加我自己的方法

    基本上,您得到的是元素列表,而不仅仅是元素,然后计算结果;如果它是零,那么它就不存在。例如:

    if driver.find_elements_by_css_selector('#element'):
        print "Element exists"
    
    请注意
    find\u elements\u by\u css\u selector
    中的“s”,以确保它可以计数

    编辑:我正在检查列表的
    长度(
    ),但我最近了解到空列表是错误的,因此您根本不需要获取列表的长度,只需要使用更简单的代码


    另外,另一个答案是使用xpath更可靠,但事实并非如此。请参见与Brian相同的内容,但在tstempko的回答中添加以下内容:

    所以我尝试了一下,效果很快:

    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)
    

    您还可以使用

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

    driver.find\u element\u by\u id(“some\u id”)。size()是类方法

    我们需要的是:


    驱动程序。通过\u id(“某些\u id”)查找\u元素。\u大小
    ,这是字典的作用:

    if-driver.find_-element_by_-id(“some_-id”)。size['width']!=0:
    
    打印“按钮存在”

    解决方案,而不使用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
    
    您可以使用如下所示的is_display()

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

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

    element\u exist=False,如果len(driver.find\u elements\u by_css\u selector('div.eiCW-'))大于0,则为True
    
    您还可以通过CSS定位器或xpath查找元素。与文本内容相比,它们的脆弱性要小得多。我认为,使用内容文本和xpath/CSS这两种方法都很容易受到设计而不是应用程序逻辑的微小更改的影响。更好的方法是通过
    id
    类名
    名称
    查找元素还应传递对象:browser=webdriver.Firefox()对于您的自定义函数,一般来说,我很少遇到符合统一匹配思想的html页面。有没有办法解决此类页面上定位器方法的混合匹配问题?@KshitijSaraogi不确定是否完全理解您的问题。如果您坚持认为您的webdriver中不可能只有“css选择器”ests——事实上这是很有可能的。在过去的6年里,我一直在这样做。@AlexOkrushko你推荐css选择器而不是xpath的原因是什么?@BoZenKhaa,至少有两个原因:开发者熟悉css选择器,这有助于提高代码的可读性;xpath在IE中有一些糟糕的性能。我对fin的一个使用点击文本是为了查看是否显示成功/不成功的flash消息。不确定是否有更好的方法来执行此操作?这些都是避免通过文本进行选择的绝对好的理由。这比上述异常处理方法快吗?@Galbrach问得好,我假设这可能取决于版本和平台,所以如果没有在这里,速度差异对您来说非常重要,我建议您在目标平台上进行测试,以获得最佳结果。但是,这里需要强调的是预优化,在这种情况下,代码可读性可能比可忽略的性能改进更为重要find元素(单数)当找不到元素时,表单抛出异常。find元素(复数形式为“s”)将返回一个空列表。在我看来,所有其他使用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
    
    res = driver.find_element_by_id("some_id").is_displayed()
    assert res, 'element not displayed!'