Python Selenium StaleElementReferenceException:消息:过时的元素引用:元素未附加到页面文档

Posted

技术标签:

【中文标题】Python Selenium StaleElementReferenceException:消息:过时的元素引用:元素未附加到页面文档【英文标题】:Python Selenium StaleElementReferenceException: Message: stale element reference: element is not attached to the page document 【发布时间】:2022-01-21 02:17:18 【问题描述】:

我正在尝试在 python 中使用 selenium 和 chromedriver 从网站上抓取数据。登录网站后,我必须从一个下拉菜单中选择一些值,但我无法使用代码单击下拉菜单。我把代码写成:

from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver,60)
element=wait.until(EC.element_to_be_clickable((By.XPATH,"//input[@id='ContentPlaceHolder1_rcmbCapacityTranch_Input']")))
element.click()

当我运行上述代码行时,我得到 StaleElementReferenceException: Message: stale element reference: element is not attached to the page document 但当我将 time.sleep(2) 包含为:

time.sleep(2)
element=wait.until(EC.element_to_be_clickable((By.XPATH,"//input[@id='ContentPlaceHolder1_rcmbCapacityTranch_Input']")))
element.click()

现在,它已成功执行并单击下拉菜单并显示值,但有时 2 秒的时间休息是不够的,我必须给 5 秒,有时我必须给 10 秒的时间休息,这会减慢执行速度,有时这 10 秒的休息时间也失败了。 我还尝试了以下代码行:

staleElement = True
while(staleElement):
    try:
        xpath="//input[@id='ContentPlaceHolder1_rcmbCapacityTranch_Input']"
        element=wait.until(EC.element_to_be_clickable((By.XPATH,xpath)))
        element.click()
        staleElement = False
    except StaleElementReferenceException:
        staleElement = True

上述代码行成功执行,但未单击下拉菜单且未显示值,但是当我在 jupyter notebook 单元格中重新执行与上面相同的代码行时,下拉菜单被选中并显示值。 所以,谁能帮我解释一下我上面提到的事情背后的原因,并在没有sleep()的情况下给我解决问题的永久解决方案。 任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

由于我没有进入该网站的凭据,我只能猜测。 所以我的猜测是:该网站使用动态 DOM。 这意味着在初始出现之后,Web 元素会继续重新构建,因此即使在 Selenium 捕捉到某些特定元素可单击或可见之后,该元素可能会立即继续更改,从而使初始元素引用变得陈旧。 您可以尝试通过两种方式处理此问题:

    首先设置wait 条件,然后设置延迟,然后设置另一个wait 条件。像这样:
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver,60)
wait.until(EC.element_to_be_clickable((By.XPATH,"//input[@id='ContentPlaceHolder1_rcmbCapacityTranch_Input']")))
time.sleep(2)
wait.until(EC.element_to_be_clickable((By.XPATH,"//input[@id='ContentPlaceHolder1_rcmbCapacityTranch_Input']"))).click()
    捕捉到元素后,尝试单击它。如果引发过时元素异常,请等待该元素再次可单击,然后再次尝试单击它,直到单击成功。使用这样的循环,您通常会在 2-3 次迭代期间单击。 所以请试试这个:
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver,60)
succeed = False
while !succeed:
    try:
        wait.until(EC.element_to_be_clickable((By.XPATH,"//input[@id='ContentPlaceHolder1_rcmbCapacityTranch_Input']"))).click()
        succeed = True
    except:
        pass

【讨论】:

以上是关于Python Selenium StaleElementReferenceException:消息:过时的元素引用:元素未附加到页面文档的主要内容,如果未能解决你的问题,请参考以下文章

selenium ide和selenium python的区别

python+selenium环境安装

python+selenium十:selenium的二次封装

Selenium 之 Mac 环境下 Python 安装 selenium 踩坑记录

selenium python怎么封装方法

python selenium不关闭当前浏览器修改配置