Reputation: 1
So my code is trying to go through a list of links (the visible text for all of which is "Annual") and then, when on the new webpage, iterate through around 20 years in a dropdown list of years and download a dataset for each year. So there are two loops. My code is getting stuck in the years loop - that is, for the same "Annual", it gets a stale element error after 2 years.
I'm working on chrome and this is the relevant part of my code:
Links = browser.find_elements_by_link_text("Annual")
for link in Links:
link.click()
time.sleep(20)
browser.switch_to_window(browser.window_handles[-1])
select = Select(browser.find_element_by_xpath('//select[@name="year"]'))
options = select.options
for index in range(0, len(options)):
select.select_by_index(index)
time.sleep(10)
excelbutton = browser.find_element_by_xpath('//a[img[@title="Download as Excel"]]').click()
the error is as follows: selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
Would appreciate any help! I've tried to go through the answers but since I'm working with 2 loops and one of them is working fine since it worked upto 2 years, I am not able to figure things out.
UPDATE: Complete error message:
Traceback (most recent call last):
File "abc", line 56, in <module>
select.select_by_index(index)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/selenium/webdriver/support/select.py", line 99, in select_by_index
for opt in self.options:
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/selenium/webdriver/support/select.py", line 47, in options
return self._el.find_elements(By.TAG_NAME, 'option')
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/selenium/webdriver/remote/webelement.py", line 527, in find_elements
{"using": by, "value": value})['value']
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/selenium/webdriver/remote/webelement.py", line 493, in _execute
return self._parent.execute(command, params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 249, in execute
self.error_handler.check_response(response)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 193, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
(Session info: chrome=67.0.3396.99)
(Driver info: chromedriver=2.40.565386 (45a059dc425e08165f9a10324bd1380cc13ca363),platform=Mac OS X 10.11.6 x86_64)
Upvotes: 0
Views: 1169
Reputation: 146510
Update-1
Since in your case stale element is on the select box, you need to change the code like below
select = Select(browser.find_element_by_xpath('//select[@name="year"]'))
options = select.options
for index in range(0, len(options)):
select.select_by_index(index)
time.sleep(10)
excelbutton = browser.find_element_by_xpath('//a[img[@title="Download as Excel"]]').click()
select = Select(browser.find_element_by_xpath('//select[@name="year"]'))
options = select.options
Original Answer
Once you click a link on page, the page may reload or change and hence your collection of elements becomes stale. So you need to apply different strategies to overcome the same
Links = browser.find_elements_by_link_text("Annual")
link_count = len(Links)
for link_index in range(0, link_count):
link = browser.find_elements_by_link_text("Annual")[link_index]
link.click()
time.sleep(20)
browser.switch_to_window(browser.window_handles[-1])
select = Select(browser.find_element_by_xpath('//select[@name="year"]'))
options = select.options
for index in range(0, len(options)):
select.select_by_index(index)
time.sleep(10)
excelbutton = browser.find_element_by_xpath('//a[img[@title="Download as Excel"]]').click()
Above code assumes that # of links remain same when you come back to the page. Also its not to say the best code possible. But this is one approach to solve the issue.
Another way to solve is to get href
of each link and then navigate to them. This of course will only work when you don't have javascript based links
Upvotes: 2