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十:selenium的二次封装