user2293224
user2293224

Reputation: 2220

Python Selenium: stale element reference: element is not attached to the page document

My program is throwing an error message "Stale element reference: element is not attached to the page document". When I looked at the previous posts (such as Python Selenium stale element fix),, I found that I am not updating the url after calling click function. I updated the url. However, it didn't fix the issue. Could anyone point out where am I making mistake please? Here is my code:

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--disable-infobars")
driver = webdriver.Chrome(chrome_options=chrome_options,executable_path="path of driver here")

driver.get("https://stackoverflow.com/users/37181/alex-gaynor?tab=topactivity")
if driver.find_elements_by_xpath("//a[@class='grid--cell fc-white js-notice-close']"):
    driver.find_element_by_xpath("//a[@class='grid--cell fc-white js-notice-close']").click()


inner_tabs = driver.find_elements_by_xpath("//div[@class='tabs']//a")

for inner_tab in inner_tabs:

    if inner_tab.text == "answers":
        inner_tab.click()
        time.sleep(3)
        driver.get(driver.current_url)
        continue

    if inner_tab.text == "questions":
        inner_tab.click()
        time.sleep(3)
        driver.get(driver.current_url)
        continue

driver.quit()

Upvotes: 1

Views: 2227

Answers (2)

pguardiario
pguardiario

Reputation: 54984

This is one of the most frustrating errors you can get with Selenium. I recommend to try it like this:

for tab in ['answers', 'questions']:
  js = "window.tab = [...document.querySelectorAll('div.tabs > a')].filter(a => a.innerText === '" + tab + "')[0]"
  driver.execute_script(js)
  driver.execute_script("if(window.tab) window.tab.click()")
  time.sleep(3)
  print(driver.current_url)

By selecting inside of the browser context you can avoid the stale references.

Upvotes: 2

ewwink
ewwink

Reputation: 19154

when you open new URL by clicking link or driver.get() it will create new document element so old element (inner_tab) will invalidate. to solve, first collect all URL then open in loop.

urls_to_visit = []

for inner_tab in inner_tabs:
    if inner_tab.text in ["questions", "answers"]:
        urls_to_visit.append(inner_tab.get_attribute("href"))

for url in urls_to_visit:
    driver.get(url)
    time.sleep(3)

Upvotes: 3

Related Questions