Python 为什么Selenium会抛出一个;StaleElementReference“;当I';我每次都会进行新的查找?
测试一个web应用程序,在该应用程序中,我需要在每个页面上运行特定的代码,因此,在“下一步”按钮未被禁用的情况下,我执行。当查看所有页面时,“下一步”按钮将被禁用,因此循环停止 在这个主题上发现了很多问题,但大多数问题都是将元素存储在变量中,在这种情况下,它完全有意义。在我的例子中,Python 为什么Selenium会抛出一个;StaleElementReference“;当I';我每次都会进行新的查找?,python,selenium,Python,Selenium,测试一个web应用程序,在该应用程序中,我需要在每个页面上运行特定的代码,因此,在“下一步”按钮未被禁用的情况下,我执行。当查看所有页面时,“下一步”按钮将被禁用,因此循环停止 在这个主题上发现了很多问题,但大多数问题都是将元素存储在变量中,在这种情况下,它完全有意义。在我的例子中,driver.find\u element\u by\u class\u name(“nextPage”)不是存储在变量中,所以不应该在每次迭代时(一次又一次)定位元素,每次都获得一个新的元素吗 现在。。。我已经设法
driver.find\u element\u by\u class\u name(“nextPage”)
不是存储在变量中,所以不应该在每次迭代时(一次又一次)定位元素,每次都获得一个新的元素吗
现在。。。我已经设法排除了错误并继续我的测试,正如您在下面看到的,但是我仍然不明白为什么会执行异常,它完全是随机的
from selenium.common.exceptions import StaleElementReferenceException
driver = webdriver.Firefox()
i = 1
while True:
try:
while driver.find_element_by_class_name("nextPage").is_enabled():
print('page' + str(i))
i += 1
driver.find_element_by_class_name("nextPage").click()
except StaleElementReferenceException:
print('An exception to a weird error, continuing loop...')
continue
break
例外消息如下:
selenium.common.exceptions.StaleElementReferenceException:消息:的元素引用已过时;元素不再附加到DOM,它不在当前框架上下文中,或者文档已刷新
最可能的原因是在搜索DOM时页面未完全加载,导致随机失败 您可以添加一个等待页面刷新吗。示例代码为:-
wait.until(lambda d: d.execute_script("return document.readyState")=='complete')
我不是一个普通的python程序员。因此,您可能还需要对代码进行一些疑难解答。算法是等待页面未就绪或未加载。这是通过javascript代码识别的::“return document.readyState”)=“complete”:
只需在i+=1之后添加上述代码
希望能有帮助 Well document.readyState只需告诉您页面是否已完全加载。所以它不会阻止您获得过时的元素,因为它无法检测任何ajax或其他正在运行的脚本 当元素存在,然后dom再次被修改/加载时,就会发生过时 为了克服这个错误,我修改了类似这样的方法(在C中):- 所以它保证了我不会再犯那个错误。你也可以点击它。或者用一个新的Click方法包装selenium Click(),该方法具有陈旧的处理功能
希望有帮助!如果还有其他问题,请告诉我。我尝试了Selenium的隐式等待,但也遇到了同样的问题。现在我在想,如果是这样的话,那么错误消息不应该是“Element not found”或者其他类似的消息,而不是元素stalled吗?隐式等待失败了,因为元素不再连接到DOM。所以含蓄的等待是行不通的。您必须在此处添加显式等待。因此,当隐式等待工作时,元素存在,但当执行其他操作时,元素被分离。。大多数情况下,因为页面仍在加载。
public static void StaleEnterTextExceptionHandler(this IWebDriver driver, By element, string value)
{
try
{
driver.EnterText(element, value);
}
catch (Exception e)
{
if (e.GetBaseException().Equals(typeof(StaleElementReferenceException)))
{
StaleEnterTextExceptionHandler(driver, element, value);
}
else
throw e;
}
}