我正在使用Python的单元测试库(unittest)和Selenium WebDriver。我尝试通过名称查找元素,但有时测试会抛出NoSuchElementException异常,而有时则不会。
我想知道是否与Selenium WebDriver等待页面加载的时间不够有关。
driver = webdriver.WhatEverBrowser()
driver.implicitly_wait(60) # This line will cause it to search for 60 seconds
它只需要在您的代码中插入一次(我通常在创建webdriver对象后立即添加)。
例如,如果您的页面由于某种原因需要花费30秒钟才能加载(购买新服务器),并且该元素是页面上最后出现的东西之一,那么它基本上会一遍又一遍地检查该元素是否存在,如果在60秒内找不到它,那么它就会抛出异常。
还要确保您的范围正确,即:如果您专注于一个框架,并且您要查找的元素不在该框架中,则不会找到该元素。
while True:
try:
x = driver.find_by_name('some_name')
break
except NoSuchElementException:
time.sleep(1)
# possibly use driver.get() again if needed
此外,请尝试使用pip install --update selenium
升级您的selenium到最新版本。
我把我的赌注放在框架上,因为我之前遇到过类似的问题 :)
再次检查你的html,并检查是否涉及到框架。如果是的话,切换到正确的框架将能够定位元素。
Python
driver.switch_to_frame("frameName")
然后查找元素。
如果没有找到,尝试按照其他人建议的等待一段时间。
处理等待元素出现的一种方法如下:
import selenium.webdriver.support.ui as ui
wait = ui.WebDriverWait(driver,10)
wait.until(lambda driver: driver.find_by_name('some_name') )
elem = driver.find_by_name('some_name')
您是正确的,webdriver不会等待页面加载,driver.get()
没有内置的默认等待。
我觉得这可能是同步问题(即webdriver速度和应用程序速度不匹配)
使用隐式等待:
driver.manage.timeouts.implicitlyWait(9000 TIMEUNITS.miliseconds)
driver.get()
是一种阻塞操作;WebDriver浏览器插件直到驱动程序确定页面已经完全加载(即所有GET请求都返回并DOM已完成)后才响应调用客户端(您所选语言的绑定)。然而,如果您有异步内容(例如修改初始页面加载完成后的DOM的JS等),您可能需要等待元素,因为它不会出现在初始完成的DOM中。设置全局隐式等待是一个快速解决方法,但如果测试运行时间对您很重要,则可能会产生负面影响。 - Silas Ray