StaleElementReferenceException: Message: stale element reference: element is not attached to the page document with Selenium and Python

。_饼干妹妹 提交于 2021-01-16 04:07:34

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!