Staleelementexception When Iterating with Python

StaleElementReferenceException in iteration with Selenium

The staleElementReferenceException is due to the list of rows gathered before loop iteration. Initially, You created a list of all rows ,named table_rows.

 table_rows = driver.find_elements_by_tag_name('tr')

Now in loop, during first iteration, your first row element is fresh and can be found by the driver. At the end of first iteration, you are doing driver.back(), your page changes/refreshes HTML DOM . All the previously gathered references are lost now. All the rows in your table_rows list are now stale. Hence, in 2nd iteration you are facing such exception.

You have to move the find row operation in the loop, so that everytime a fresh reference is found on target application. The psuedocode shall do Something like this.

total_rows = driver.find_elements_by_tag_name('tr').length()

for i in total_rows
driver.find_element_by_xpath('//tr[i]')
.. further code..

StaleElementReferenceException on Python Selenium while using for loop

You have to define this

 driver.find_elements_by_xpath('//a[@class="sc-dBAPYN kcrxQo"]')

again in loop.

Code :

number_of_titles = len(driver.find_elements_by_xpath('//a[@class="sc-dBAPYN kcrxQo"]'))

#this is block of code which is error prone
j = 0
for i in range(number_of_titles):
time.sleep(5)
titles = driver.find_elements_by_xpath('//a[@class="sc-dBAPYN kcrxQo"]')
driver.execute_script("window.scrollTo(0, 0);")
element = titles[j].find_element_by_xpath('.//div//h4')
driver.execute_script("arguments[0].click();", element)
time.sleep(3)
j = j +1
name_of_rests = driver.find_element_by_css_selector('#root > div > main > div > section.sc-kxynE.jzTfFZ > section > section > div > div > div > h1').text
res_list.append(name_of_rests)

driver.back()

Selenium stale element reference in for loop

Seems like I found the solution, but can protect it that it's the best, will dig into it more:

elements = driver.find_elements(By.CSS_SELECTOR, 'div.g')
for n, el in enumerate(elements):
elements = driver.find_elements(By.CSS_SELECTOR, 'div.g')
elements[n].click()
time.sleep(1)
driver.back()
time.sleep(1)
driver.quit()

try to find elements, then move start the loop and find the same result and get items from that loop by item number from enumarate function.

from time import sleep
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains

def company_info(driver):
com_name = driver.find_element_by_xpath('Enter your site xpath')
print(com_name.text)

com_addr = driver.find_element_by_xpath('Enter your site xpath')
print(com_addr.text)

com_tel = driver.find_element_by_xpath('Enter your site xpath')
print(com_tel.text)

com_fax = driver.find_element_by_xpath('Enter your site xpath')
print(com_fax.text)

driver = webdriver.Chrome()
url_search = 'Enter your site URL'

#input values
web_open_wait = 5
web_close_wait = 3
driver.get(url_search)
sleep(web_open_wait)

check_names = driver.find_elements_by_xpath('//*[@id="frm"]/table/tbody/tr[1]/td/a'
for n, el in enumarate(check_names, start=1):
check_names = driver.find_elements_by_xpath('//*[@id="frm"]/table/tbody/tr[%d]/td/a' % n)
check_name[el].click()

company_info(driver)
driver.back()

driver.quit()

Getting StaleElementReferenceException when iterating through a list of WebElements

The moment you click on the element or back() in the browser the element reference will updated in the selenium so you can not point to the elements with the old references and which led to the StatleElementException.

Consider this approach when you have to iterate through multiple elements interaction.

List<WebElement> bestsellers = driver.findElements(By.xpath("xpath of bestsellers"));
for(int i=0; i<bestsellers.size(); i++) {
System.out.println("Current Seller " + i);
// here you are getting the elements each time you iterate, which will get the
// latest element references
driver.findElements(By.xpath("xpath of bestsellers")).get(i).click();
clickOnAddToCartButton();
driver.navigate().back();

}

StaleElementReferenceException while looping over list

Problem Explanation :

See the problem here is, that you have defined a list corporaties = driver.find_elements_by_xpath("//button[@role='option']") and then iterating this list, and clicking on first element, which may cause some redirection to a new page, or in a new tab etc.

so when Selenium try to interact with the second webelement from the same list, it has to come back to original page, and the moment it comes back, all the elements become stale in nature.

Solution :

one of the basic solution in this cases are to define the list again, so that element won't be stale. Please see the illustration below :-

Code :

corporaties=[]
corporaties = driver.find_elements_by_xpath("//button[@role='option']")
# Iteration
j = 0
for i in range(len(corporaties)):
elements = driver.find_elements_by_xpath("//button[@role='option']")
elements[j].click()
j = j + 1 # select institution
driver.find_element_by_class_name("close-button").click() # close pop-up screen
action.move_to_element(element_to_select).perform() # select download button
driver.find_element_by_id("utilsmenu").click() # click download button
driver.find_element_by_id("utils-export-spreadsheet").click() # pick export to excel
driver.find_element_by_id("baseGeo").click() # select drop down menu for next iteration
time.sleep(2)


Related Topics



Leave a reply



Submit