[英]Checking if an element exists with Python Selenium
我有个问题; 我是用Selenium(Firefox)web驱动打开一个网页,点击几个链接等,然后截图。
我的脚本在 CLI 中运行良好,但是当通过cron 作业运行时,它没有通过第一个 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()
A) 我如何检查链接是否真的被 Python 拾取了? 我应该使用 try/catch 块吗?
B) 是否有比 LINK_TEXT 更好/更可靠的定位DOM元素的方法? 例如,在jQuery中,您可以使用更具体的选择器 $('a.lnk:contains(log in)').do_something();
我已经解决了主要问题,这只是手指的麻烦。 我用不正确的参数调用脚本 - 一个简单的错误。
我仍然想要一些关于如何检查元素是否存在的指示。 此外,还有一个隐式/显式等待的示例/解释,而不是使用糟糕的 time.sleep() 调用。
一种)
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 selectors 。 我仍然建议不要混合/使用“按 id”、“按名称”等,而是使用一种方法。
提供的解决方案对我来说似乎都不是最简单的,所以我想添加我自己的方式。
基本上,您获得元素列表,而不仅仅是元素,然后计算结果; 如果它为零,则它不存在。 例子:
if driver.find_elements_by_css_selector('#element'):
print "Element exists"
注意find_elements_by_css_selector
的“s”以确保它是可数的。
编辑:我正在检查列表的len(
,但我最近了解到空列表是错误的,因此您根本不需要获取列表的长度,而是使用更简单的代码。
另外,另一个答案说使用 xpath 更可靠,但事实并非如此。 请参阅css-selector 和 Xpath 有什么区别? 哪个更好(根据性能和跨浏览器测试)?
A) 是的。 检查元素是否存在的最简单方法是在try/catch
简单地调用find_element
。
B) 是的,我总是尝试在不使用文本的情况下识别元素,原因有两个:
解决方案:
对于后续问题,使用try/catch
可以判断元素是否存在,并且可以在此处找到等待的好示例: http : //seleniumhq.org/docs/04_webdriver_advanced.html
没有 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
与布赖恩相同,但从 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)
你也可以更简洁地使用
driver.find_element_by_id("some_id").size != 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'
使用最新的 Selenium,您现在可以使用您现在可以使用.is_displayed()
:
https://www.selenium.dev/documentation/webdriver/elements/information/
你可以像下面这样使用 is_displayed()
res = driver.find_element_by_id("some_id").is_displayed()
assert res, 'element not displayed!'
如果数组的长度等于 0 元素不存在,您可以通过可用的方法查找元素并检查响应数组长度。
element_exist = False if len(driver.find_elements_by_css_selector('div.eiCW-')) > 0 else True
当您知道元素不存在时,隐式等待可能是一个问题。 我创建了一个简单的上下文管理器来避免那些等待时间
class PauseExplicitWait(object):
"""
Example usage:
with PauseExplicitWait(driver, 0):
driver.find_element(By.ID, 'element-that-might-not-be-there')
"""
def __init__(self, driver, new_wait=0):
self.driver = driver
self.original_wait = driver.timeouts.implicit_wait
self.new_wait = new_wait
def __enter__(self):
self.driver.implicitly_wait(self.new_wait)
def __exit__(self, exc_type, exc_value, exc_tb):
self.driver.implicitly_wait(self.original_wait)
您可以通过 find_elements 检查,如果结果为空,则该元素不存在
if driver.find_elements(By.SOMETHING, "#someselector") == []:
continue # that element is not exist
A)使用.is_displayed()
如解释
https://www.selenium.dev/documentation/webdriver/elements/information/
# After navigating to the url
# Get boolean value for is element display
is_button_visible = driver.find_element(By.CSS_SELECTOR, "[name='login']").is_displayed()
使用“is_button_visible”继续您的代码逻辑进行分支。
B)参考@Sam Woods 接受的答案
el = WebDriverWait(driver, timeout=3).until(lambda d: d.find_element(By.TAG_NAME,"p"))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.