当前位置: 首页 > 知识库问答 >
问题:

Selenium with Python:Stale元素引用异常

邓欣德
2023-03-14

在使用Python进行测试驱动开发时,我目前在迁移后立即运行功能测试时遇到了“StaleElementReferenceException”。以下是错误的全文:

ERROR: test_start_and_retrieve_list (__main__.NewVisitorTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "functional_tests.py", line 53, in test_start_and_retrieve_list
    rows = table.find_elements_by_tag_name('tr')
  File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/webelement.py", line 237, in find_elements_by_tag_name
    return self.find_elements(by=By.TAG_NAME, value=name)
  File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/webelement.py", line 527, in find_elements
    {"using": by, "value": value})['value']
  File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/webelement.py", line 493, in _execute
    return self._parent.execute(command, params)
  File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/webdriver.py", line 256, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of <table id="id_list_table"> stale: either the element is no longer attached to the DOM or the page has been refreshed


----------------------------------------------------------------------
Ran 1 test in 8.735s

FAILED (errors=1)

以下是测试:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import unittest

class NewVisitorTest(unittest.TestCase): 

    def setUp(self):
        self.browser = webdriver.Firefox()
        self.browser.implicitly_wait(3)

    def tearDown(self):
        self.browser.close()

    def check_for_row(self, row_text):
        table = self.browser.find_element_by_id('id_list_table')
        rows = table.find_elements_by_tag_name('tr')
        self.assertIn(row_text, [row.text for row in rows])

    def test_start_and_retrieve_list(self):    
        self.browser.get('http://localhost:8000')

        self.assertIn('To-Do', self.browser.title)
        header_text = self.browser.find_element_by_tag_name('h1').text
        self.assertIn('To-Do', header_text)

        inputbox = self.browser.find_element_by_id('id_new_item')
        self.assertEqual(
            inputbox.get_attribute('placeholder'),
            'Enter a to-do item'
        )

        inputbox.send_keys('Buy peacock feathers')

        inputbox.send_keys(Keys.ENTER)
        self.check_for_row('1: Buy peacock feathers')

        inputbox = self.browser.find_element_by_id('id_new_item')
        inputbox.send_keys('Use peacock feathers to make a fly')
        inputbox.send_keys(Keys.ENTER)

        table = self.browser.find_element_by_id('id_list_table')
        rows = table.find_elements_by_tag_name('tr')
        self.check_for_row('1: Buy peacock feathers')
        self.check_for_row('2: Use peacock feathers to make a fly')

        self.fail('Finish the test!')

if __name__ == '__main__':
    unittest.main(warnings='ignore')

如何配置测试以防止出现这种情况?Selenium自己的页面表示,页面刷新时可能会出现此问题,但这是应用程序逻辑的一个必要部分,因为到目前为止,它已经配置好了。

共有3个答案

关玮
2023-03-14

我没有使用python,但使用过java/selenium。但是,我可以给你一个克服陈腐的想法。

一般来说,如果元素属性或其他东西在启动webelement后发生变化,我们将获得陈旧异常。例如,在某些情况下,如果用户试图在同一页面上点击相同的元素,但在页面刷新后,会获得stalle元素异常。

为了克服这个问题,我们可以创建新的webelement,以防页面被更改或刷新。下面的代码可以给你一些想法。(它是java的,但概念是一样的)

示例:

webElement element = driver.findElement(by.xpath("//*[@id='StackOverflow']"));
element.click();
//page is refreshed
element.click();//This will obviously throw stale exception

为了克服这个问题,我们可以将xpath存储在一些字符串中,并使用它创建一个新的webelement。

String xpath = "//*[@id='StackOverflow']";
driver.findElement(by.xpath(xpath)).click();
//page has been refreshed. Now create a new element and work on it
driver.fineElement(by.xpath(xpath)).click();   //This works

另一个例子:

for(int i = 0; i<5; i++)
{
  String value = driver.findElement(by.xpath("//.....["+i+"]")).getText);
  System.out.println(value);
} 

希望这对你有帮助。谢谢

沈飞翔
2023-03-14

我已经使用硒一段时间了,所以我理解陈旧元素异常的挣扎。虽然不完美,但selenium提供了一系列“等待”命令,以允许网站加载完成。不幸的是,它并不完美,因为加载每次运行需要不同的时间,但这些是selenium提供的工具。

胡越泽
2023-03-14

添加这些导入:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions

换线

inputbox.send_keys(Keys.ENTER)
self.check_for_row('1: Buy peacock feathers')

致:

inputbox.send_keys(Keys.ENTER)

WebDriverWait(self.browser, 10).until(
            expected_conditions.text_to_be_present_in_element(
                (By.ID, 'id_list_table'), 'Buy peacock feathers'))

self.check_for_row('1: Buy peacock feathers')

这将time.sleep(1)替换为更合理的东西

 类似资料:
  • 嗨,我是硒的新手 我正在使用,已经尝试了和驱动程序。 我正在运行一个循环。有趣的是,循环有时会工作3、2次,它并不总是在同一次迭代中失败。我假设它与某种竞争条件有关(例如等待页面加载)。如果我在调试模式下运行,它似乎可以完美地工作。 我已经尝试了其他答案的建议,比如显式等待和隐式等待,但仍然没有帮助。也许如果你看到密码你可以帮我一把。 这是一个循环。 解决方案 解决方案是彻底破解。我仍然不明白,但

  • 好的,我阅读了所有其他的链接,我尝试了上述不同解决方案的变体,但是它们都不适合我。 我的问题是,我有以下代码: 然而,我得到了以下错误: 这是篮子图标的css路径,它在菜单上。 网站是GWT,步骤如下:1。点击物品添加到购物篮2。增加到第三篮。点击篮子进入篮子。 然而,我似乎无法做到这一点。

  • 我正在使用for循环来处理表元素。在第一次迭代中,它将在页面上搜索所需的元素。如果该元素在该页面上不可用,那么它将在第二个页面上搜索。如果元素在第一个页面上可用,Webdriver会成功地找到该元素,但如果元素在第一个页面上不可用,则它会在第二个页面上查找该元素。但在这里,for循环失败,出现称为“stale Element exception”的异常。 错误消息: 线程“main”org.ope

  • 我正在尝试自动执行以下操作: 启动https://www.flipkart.com 我在线程“主”状态元素引用中得到期望:元素没有附加到miButton()方法中的页面文档。 请参阅错误详细信息部分。 HTML代码 Mi按钮点击-HTML 基类: 页面类 错误详细信息 线程“main”组织中出现异常。openqa。硒。StaleElementReferenceException:stale ele

  • 我知道这方面有很多问题,但似乎没有任何帮助。使用键打开一个新的选项卡或窗口,这样元素就不会过时,这并没有任何作用。不会打开新选项卡。它什么也没做。我正在抓取一个网站,主页上有一个链接列表,我需要通过点击每个链接循环,并从每个链接获取数据。在第一次迭代之后,当它回到主页面时,元素显然已经过时了。这是我第一次使用Selenium,所以我为这个天真的问题道歉,但我已经被困了好几天了,现在我迫切需要一些帮

  • 下面是我正在努力工作的代码。 我从一个站点地图页面获取所有锚元素,然后将所有这些元素放入一个列表中。然后,我使用从所有这些元素获取URL。在这里之前,代码运行良好。 然而,之后我将这些URL作为参数,并将其传递到方法,以使用。代码一直工作到第一个链接,但一旦加载了第一个页面,就会出现stale元素异常。