selenium python onclick() gives StaleElementReferenceException

你离开我真会死。 提交于 2020-01-06 06:08:25

问题


The developer changed the code to use an onclick() DOM element instead of an url. So Now I need to reload page all the time to prevent it from getting stale. How can I do this with a single find_elements_by_xpath? I assume it is the document.*.submit() that needs the DOM?

https://localhost:4778/ruleengine/AlarmTest?category=Alert#, text:(Force), onclick():document.Forceee0deabfba2341d2a0988779499f5530.submit()

Old code now fails:

driver.get(alarmurl)
elems = driver.find_elements_by_xpath("//a[contains(text(), '(Force)')]")
for el in elems:
    el.click()

My current workaround is to reload the page after every click, but we may have 3000 events to remove, making it horrendously slow.

driver.get(alarmurl)
elems = driver.find_elements_by_xpath("//a[contains(text(), '(Force)')]")
while len(elems) > 0:
    driver.get(alarmurl)
    elems = driver.find_elements_by_xpath("//a[contains(text(), '(Force)')]")
    elems[0].click()

Thanks


回答1:


I dont think you have to reload the entire page if you encounter StaleElementReferenceException but I may be wrong too. It happens When the element is no longer attached to the DOM, search for the element again to reference the element

The below code may not clear your issue, but should help you start implementing a better solution

driver.get(alarmurl)
elems = driver.find_elements_by_xpath("//a[contains(text(), '(Force)')]")
for el in elems:
    try:
      el.click()
    except StaleElementReferenceException:
       # find the element again and click



回答2:


You can fix your code as below:

driver.get(alarmurl)
# get initial events number
elems_count = len(driver.find_elements_by_xpath("//a[contains(text(), '(Force)')]"))

# execute click() for each event
for _ in range(elems_count):
    driver.find_elements_by_xpath("//a[contains(text(), '(Force)')]")[0].click()

P.S. You also might need to wait until events number decreased by 1 after each click in case events removes too slow... or apply another approach:

driver.get(alarmurl)
# get initial events number
elems_count = len(driver.find_elements_by_xpath("//a[contains(text(), '(Force)')]"))

# execute click() for each event. Starting from the last one
for index in range(elems_count):
    driver.find_elements_by_xpath("//a[contains(text(), '(Force)')]")[elems_count - index - 1].click()


来源:https://stackoverflow.com/questions/47512791/selenium-python-onclick-gives-staleelementreferenceexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!