python - StaleElementReferenceException:消息:过时的元素引用:元素未使用 Selenium 和 Python 附加到页面文档
问题描述
我正在为一个包含下拉菜单的网站开发 selenium。
首先,我们有基本代码:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import Select
options = Options()
browser = webdriver.Chrome(chrome_options= options,executable_path=r'C:\Users...chromedriver.exe')
browser.get('http://.../')
然后我正在实施该部分以处理下拉菜单。我的目标是为每个下拉选项执行一些操作。
当我在做:
dropdown = Select(browser.find_element_by_name('DropDownList'))
options = dropdown.options
for index in range(0, len(options) - 1):
dropdown.select_by_index(index)
#browser.refresh()
print(index)
它工作得很好。
但是,当我为每个下拉选项执行一些操作时:
dropdown = Select(browser.find_element_by_name('DropDownList'))
options = dropdown.options
for index in range(0, len(options) - 1):
dropdown.select_by_index(index)
browser.refresh()
print(index)
然后只有第一个下拉选项运行,然后显示错误:
0
---------------------------------------------------------------------------
StaleElementReferenceException Traceback (most recent call last)
<ipython-input-31-fa7ad153fc9f> in <module>
5
6 for index in range(0, len(options) - 1):
----> 7 dropdown.select_by_index(index)
8 browser.refresh()
9 print(index)
~\anaconda3\lib\site-packages\selenium\webdriver\support\select.py in select_by_index(self, index)
97 """
98 match = str(index)
---> 99 for opt in self.options:
100 if opt.get_attribute("index") == match:
101 self._setSelected(opt)
~\anaconda3\lib\site-packages\selenium\webdriver\support\select.py in options(self)
45 def options(self):
46 """Returns a list of all options belonging to this select tag"""
---> 47 return self._el.find_elements(By.TAG_NAME, 'option')
48
49 @property
~\anaconda3\lib\site-packages\selenium\webdriver\remote\webelement.py in find_elements(self, by, value)
683
684 return self._execute(Command.FIND_CHILD_ELEMENTS,
--> 685 {"using": by, "value": value})['value']
686
687 def __hash__(self):
~\anaconda3\lib\site-packages\selenium\webdriver\remote\webelement.py in _execute(self, command, params)
631 params = {}
632 params['id'] = self._id
--> 633 return self._parent.execute(command, params)
634
635 def find_element(self, by=By.ID, value=None):
~\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py in execute(self, driver_command, params)
319 response = self.command_executor.execute(driver_command, params)
320 if response:
--> 321 self.error_handler.check_response(response)
322 response['value'] = self._unwrap_value(
323 response.get('value', None))
~\anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py in check_response(self, response)
240 alert_text = value['alert'].get('text')
241 raise exception_class(message, screen, stacktrace, alert_text)
--> 242 raise exception_class(message, screen, stacktrace)
243
244 def _value_or_default(self, obj, key, default):
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
(Session info: chrome=83.0.4103.116)
谁能帮我解决这个问题?谢谢
解决方案
此错误消息...
StaleElementReferenceException: Message: The element reference of <span class="pagnCur"> 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
...意味着元素的先前引用现在是stale
,并且先前的元素引用不再存在于网页的 DOM 树中。
此异常背后的常见原因可能是以下任一原因:
- 该元素已更改其在 HTML DOM 中的位置。
- 该元素不再附加到 DOM 树。
- 元素所在的网页已刷新。
- 之前的 element 实例已被 JavaScript 刷新。
这个用例
相关 HTML 方面的更多细节将有助于我们构建更规范的答案。但是,根据您的第一个代码块:
dropdown = Select(browser.find_element_by_name('DropDownList'))
options = dropdown.options
for index in range(0, len(options) - 1):
dropdown.select_by_index(index)
print(index)
似乎选择<option>
元素不会导致DOM Tree发生任何变化。
但是在您的第二个代码块中:
dropdown = Select(browser.find_element_by_name('DropDownList'))
options = dropdown.options
for index in range(0, len(options) - 1):
dropdown.select_by_index(index)
browser.refresh()
print(index)
当您在HTML DOM中的所有元素被刷新并且旧的引用变得陈旧browser.refresh()
之前调用。print(index)
因此,当您尝试print(index)
WebDriver抱怨StaleElementReferenceException
解决方案
你不需要browser.refresh()
之前的行print(index)
。删除线browser.refresh()
将解决您的问题。
参考
您可以在以下位置找到一些相关的详细讨论:
推荐阅读
- html - 如何在元素中强制状态悬停
- java - 跳棋和井字游戏的面向对象设计
- javascript - 在 for 循环中使用 setTimeout
- vba - 预期的用户定义类型,而不是项目
- amazon-web-services - Cloudformation AWS:使用参数将 IP 地址分配给 CustomerGateway
- c++ - 在网站上:godbolt.org,只有那里:我如何使用 std::thread?
- javascript - 需要帮助在反应中将道具从父元素传递给子元素
- c# - Naudio wav 格式问题
- python - 为什么我无法使用 requests Python 登录?
- reactjs - 如何从文件中导出/导入多个样式组件?