问题
I am working on selenium for a website that consists of dropdown menu.
At first, we have the basic codes:
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://.../')
Then I am implementing the part to work on the dropdown. My goal is to perform something for each dropdown option.
When I am doing:
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)
It is working just fine.
However, when I am performing some stuff for each dropdown option:
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)
Then only the first dropdown option runs and then it shows error:
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)
Can anyone help me solve this issue? Thanks
回答1:
This error message...
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
...implies that the previous reference of the element is now stale
and the previous element reference is no longer present within the DOM TREE of the webpage.
The common reasons behind this this exception can be either of the following:
- The element have changed it's position within the HTML DOM.
- The element is no longer attached to the DOM TREE.
- The webpage on which the element was part of has been refreshed.
- The previous instance of element has been refreshed by a JavaScript.
This usecase
A bit of more details interms of the relevant HTML would have helped us to construct a more canonical answer. However, as per your first code block:
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)
It seems selecting the <option>
elements doesn't result in any changes with in the DOM Tree.
But in your second code block:
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)
As you are invoking browser.refresh()
before print(index)
all the elements within the HTML DOM gets refreshed and the olden references becomes stale.
Hence when you try to print(index)
WebDriver complains of StaleElementReferenceException
Solution
You don't need the browser.refresh()
line before print(index)
. Removing the line browser.refresh()
will solve your issue.
Reference
You can find a couple of relevant detailed discussion in:
- StaleElementReference Exception in PageFactory
来源:https://stackoverflow.com/questions/62818340/staleelementreferenceexception-message-stale-element-reference-element-is-not