PeteF
PeteF

Reputation: 3

How do I get round a Stale Element Reference exception when using Chrome Driver

I am trying to automate my login to a website I use. I have a Python script which successfully finds and updates the username and password, but when I try to 'click' Login, I get the stale element exception.

The code is:

from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://waveleisure.gs-signature.cloud/Connect/mrmLogin.aspx")
driver.implicitly_wait(10)
elements = driver.find_elements(By.TAG_NAME, "input")
print(len(elements), " elements found")
for el in elements:
    if el.accessible_name == "Email Address":
        print("got email address")
        el.send_keys("****@gmail.com")
    elif el.accessible_name == "Password":
        print("got password")
        el.send_keys("****")
driver.implicitly_wait(10)
elements = driver.find_elements(By.TAG_NAME, "input")
for el in elements:
    if el.accessible_name == "Login":
        print("got login")
        el.click()

Running the script above gives:

DevTools listening on ws://127.0.0.1:52650/devtools/browser/09db5c0e-52e4-45a4-8499-f5703dde1f6e
10  elements found
got email address
got password
got login
Traceback (most recent call last):
  File "C:\Workspace\Booking\WavesBooking.py", line 28, in <module>
    if el.accessible_name == "Login":
       ^^^^^^^^^^^^^^^^^^
  File "C:\Users\pete_\AppData\Local\Programs\Python\Python312\Lib\site-packages\selenium\webdriver\remote\webelement.py", line 303, in accessible_name
    return self._execute(Command.GET_ELEMENT_ARIA_LABEL)["value"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pete_\AppData\Local\Programs\Python\Python312\Lib\site-packages\selenium\webdriver\remote\webelement.py", line 395, in _execute
    return self._parent.execute(command, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pete_\AppData\Local\Programs\Python\Python312\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 354, in execute
    self.error_handler.check_response(response)
  File "C:\Users\pete_\AppData\Local\Programs\Python\Python312\Lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 229, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found
  (Session info: chrome=130.0.6723.92); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#stale-element-reference-exception

Upvotes: 0

Views: 45

Answers (2)

Idris Olokunola
Idris Olokunola

Reputation: 436

this happened because the element you’re trying to interact with has reloaded on the webpage so it’s no longer available at the original reference.

What you can do is, Right before clicking the "Login" button, refind and retry up to 3 times if needed it since the page might have changed. do it like this

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import StaleElementReferenceException
import time

driver = webdriver.Chrome()
driver.get("https://waveleisure.gs-signature.cloud/Connect/mrmLogin.aspx")
driver.implicitly_wait(10)

elements = driver.find_elements(By.TAG_NAME, "input")
for el in elements:
    if el.accessible_name == "Email Address":
        el.send_keys("****@gmail.com")
    elif el.accessible_name == "Password":
        el.send_keys("****")

for _ in range(3):
    try:
        elements = driver.find_elements(By.TAG_NAME, "input")
        for el in elements:
            if el.accessible_name == "Login":
                el.click()
                break
        break
    except StaleElementReferenceException:
        time.sleep(1)

Upvotes: 0

John Gordon
John Gordon

Reputation: 33275

This loop is the problem:

elements = driver.find_elements(By.TAG_NAME, "input")
for el in elements:
    if el.accessible_name == "Login":
        print("got login")
        el.click()

Executing el.click() the first time causes a new page to be loaded, so the remaining items in elements now refer to elements that are no longer on the current page.

Maybe you should break out of that loop after clicking on the Login element?

Upvotes: 0

Related Questions