【问题标题】:StaleElementReferenceException on FirefoxWebElement.get_attribute even after WebDriverWait即使在 WebDriverWait 之后,FirefoxWebElement.get_attribute 上的 StaleElementReferenceException
【发布时间】:2021-01-05 22:36:18
【问题描述】:

我正在尝试使用 Selenium 获取网站(在 React 生产版本上运行)上特定元素的内部文本。我正在执行以下操作:

driver = webdriver.Firefox()
driver.get('some site using React')

WebDriverWait(driver, 10).until(
    expected_conditions.text_to_be_present_in_element(
        (By.CSS_SELECTOR, '.parent p'), 
        'some text here'
    )
)

这一切都有效 - 事实上,我什至可以在之后访问该元素:

elem = driver.find_element(By.CSS_SELECTOR, '.parent p')
print(elem)
# -> <selenium.webdriver.firefox.webelement.FirefoxWebElement (session="57b82b73-0c6a-40c5-97e1-b5861b3d43e6", element="736edc49-cef0-4723-b69e-afabd80f1e9d")>

但是,一旦我尝试对此进行任何操作,就会收到 StaleElementReferenceException。例如,

print(elem.get_attribute('innerText'))

print(elem.text)

都抛出以下错误:

selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of <p> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed

我也尝试将expected_conditions.text_to_be_present_in_element 替换为expected_conditions.presence_of_element_located,但问题仍然存在。我不知道为什么我能够成功等待元素的加载,甚至认识到所述元素中的文本与我的格式匹配(即我们能够以某种方式阅读文本),甚至能够打印元素本身- 但是当我尝试获取它的文本时,即使只是读取一个属性(而不是调用一个方法),我也会得到这个异常。有时,也许每三次尝试左右,它就会起作用 - 但随后又回到不工作状态。

我怎样才能绕过这个错误,以便在我的文本与我的预期格式匹配时立即访问它(即包括“此处包含一些文本”)?


根据@PDHide 的要求,这是我的完整代码:

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

from selenium import webdriver

driver = webdriver.Firefox()

while True:  # Running repeatedly, to ensure that the solution works consistently over multiple executions
    driver.get('url')
    WebDriverWait(driver, 10).until(
        EC.text_to_be_present_in_element(
            (By.CSS_SELECTOR, '.parent p'), 
            'some text here'
        )
    )

    print(driver.find_element(By.CSS_SELECTOR, '.parent p').get_attribute('innerText'))

这通常适用于一两次执行,然后中断并恢复为抛出 StaleElementReferenceException

【问题讨论】:

    标签: python python-3.x selenium


    【解决方案1】:

    定位元素后修改 DOM(页面 HTML)的陈旧元素状态。

    例如:

     print(elem.get_attribute('innerText'))
     clicksomebutton.click()
     print(elem.get_attribute('innerText'))
    

    如果单击刷新或在屏幕上加载某些内容,则会失败。为此,您必须再次找到元素。

     print(elem.get_attribute('innerText'))
     clicksomebutton.click()
     print(driver.find_element_by_xpath('blabla').get_attribute('innerText'))
    
    
    
    
     
    

    【讨论】:

    • 我已经尝试过了,它确实有效...偶尔。但是,每三倍左右,它仍然会中断,尤其是在循环中的多个站点上运行它时(我意识到,我没有在上面的 MVE 中指定)。无论如何感谢您的建议!
    • @GezaKerecsenyi 你必须添加显式等待
    • 请在抛出错误的地方添加完整代码
    • “显式等待”是什么意思?我还在用expected_conditionWebDriverWait。我的“完整代码”如上;我只是多次运行相同的东西来对其进行压力测试,运行一两次后它就坏了。
    • @GezaKerecsenyi 而不是将代码拆分为部分,而是添加显示实际代码流的完整代码,并在您尝试 elem.getText 时提及系统状态
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 2021-03-17
    • 2014-12-03
    • 2015-01-16
    • 2016-03-17
    • 2023-04-10
    相关资源
    最近更新 更多