Vignesh Elumalai
Vignesh Elumalai

Reputation: 11

How to solve 'StaleElementReferenceException: Message: stale element reference: stale element not found'?

Here's my code:

elements = driver.find_elements(By.CLASS_NAME, 'name')
for i in elements:
    i.click()
    driver.back()

Error: selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found.

When I tried this...

elements = driver.find_elements(By.CLASS_NAME, 'name')
for i in range(len(elements)):
    elements[i].click()
    time.sleep(2)
    driver.back()
    elements = driver.find_elements(By.CLASS_NAME, 'name')

...it shows list index out of range error.

First I stored a list of web elements (links) in a list, then I looped through the list and told selenium to click the web element (going to another page and coming back). Whenever it tries to click the second list item, it shows this error: stale element not found.

How can I make selenium click the web element, come back to the original page, and then click the next element without errors?

Upvotes: 1

Views: 84

Answers (1)

RichEdwards
RichEdwards

Reputation: 3753

You get StaleElementException when you're trying to interact with an object after the page has changed.

When you go back and forwards between pages, you'll also need to ensure you have the correct wait strategy. Selenium's default is "the page is loaded", but this does not mean the content is ready, especially if it's loaded though javascript.

Try using an iterative identifier along with your collection.

#wait strategy example:
driver.implicitly_wait(10)

#collect the items you want to use
elements = driver.find_elements(By.XPATH, '(//*[@class="name"])')

#loop your items as just a count
for i in range(len(elements)):
   # find your one specific element based on i.  XPATH iterators start at 1, python starts at 0 (so add 1)
   # This line inherits the implicit wait time
   driver.find_element(By.XPATH, f'(//*[@class="name"])[{i+1}]').click()
   
   #...Do your reason for clicking here...
   
   driver.back()

Some notes:

  • I changed your class_name to an xpath equivielent to allow it to be iterated in the identifier
  • try defining driver.implicitly_wait(10) (that's 10 seconds) once at the start of your script. When doing the find_element(...), this will wait up to 10 seconds for an element to appear before throwing errors - more on wait strategies here
  • If you're struggling to get this to work, debug the code and walk through each line slowly. A lot of selenium issues arise from synchronisation. You're the only one who knows the content of your page - so perhaps an explicit wait might work better for you,

Upvotes: 0

Related Questions