StaleElementReferenceException on Python Selenium

后端 未结 9 2067
孤独总比滥情好
孤独总比滥情好 2020-11-27 13:28

I am getting the following error while using Selenium in python:

selenium.common.exceptions.StaleElementReferenceException: Message: u\'stale element referen         


        
相关标签:
9条回答
  • 2020-11-27 13:40

    Beyond the answers here, if you are using ActionChains, and the page has changed, be sure to reinstantiate your ActionChains object (dont reuse an old one), otherwise your ActionChain will be using a stale DOM. I.e. do this;

    action_chain = ActionChains(driver)     
    action_chain.double_click(driver.find_element_by_xpath("//tr[2]/p")).perform()
    

    Or better yet dont use an instantiation;

    ActionChains(driver).double_click(driver.find_element_by_xpath("//tr[2]/p")).perform()
    
    0 讨论(0)
  • 2020-11-27 13:48

    This is the python solution for this problem:

    def clickAndCatchStaleRefException(locator):
    
    
    
        driver = sel2._current_browser()
        result = False
        attempts = 0
    
        locator = locator[6:]
        # This line is optional because sometimes you pass a xpath from a varibles file
        # that starts with 'xpath='. This should be omitted otherwise the find_element_by_xpath 
        # function will throw an error.
        # But if you pass an xpath directly you don't need this
    
    
        while attempts < 2:
            try:
                driver.find_element_by_xpath(locator).click()
                result = True
                break
            except EC as e:
                raise e
            finally:
                attempts += 1
        return result
    
    0 讨论(0)
  • 2020-11-27 13:49

    When webpage got refreshed or switched back from different window or form and trying to access an element user will get staleelementexception.

    Use webdriverwait in try --except block with for loop: EX :

    Code in which I got staleelementexception :


    driver.find_element_by_id(tc.value).click()
    

    driver.find_element_by_xpath("xpath").click()


    Fix :

    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    driver.find_element_by_id(tc.value).click()
    for i in range(4):
       try:
            run_test = WebDriverWait(driver, 120).until( \
            EC.presence_of_element_located((By.XPATH, "xpath")))
            run_test.click()
            break
       except StaleElementReferenceException as e:
            raise e
    
    0 讨论(0)
  • 2020-11-27 13:50

    It means the element is no longer in the DOM, or it changed.

    The following code will help you find the element by controlling and ignoring StaleElementExceptions and handling them just like any other NoSuchElementException. It waits for the element to NOT be stale, just like it waits for the element to be present. It also serves as a good example on how to properly wait for conditions in Selenium.

    from selenium.common.exceptions import NoSuchElementException
    from selenium.common.exceptions import StaleElementReferenceException
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions
    
    my_element_id = 'something123'
    ignored_exceptions=(NoSuchElementException,StaleElementReferenceException,)
    your_element = WebDriverWait(your_driver, some_timeout,ignored_exceptions=ignored_exceptions)\
                            .until(expected_conditions.presence_of_element_located((By.ID, my_element_id)))
    

    To better understand the problem, imagine you are inside a for loop and think what happens during the iterations:

    1. something changes when you click on the element (last line)
    2. So the page is changing
    3. You enter the next iteration. Now are trying to find a new element (your first line inside the loop).
    4. You found the element
    5. It finishes changing
    6. You try to use it by getting an attribute
    7. Bam! The element is old. You got it in step 4, but it finished changing on step 5
    0 讨论(0)
  • 2020-11-27 13:52

    I Would like to add one more solution here which is worked for me.

    I was trying to access the button in the top menu panel on my webpage after refreshing the content area on the same page, Which gave me the following error,

        raise exception_class(message, screen, stacktrace)
    selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of <span id="dk1-combobox" class="dk-selected combinationText visibleElements "> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed
    

    Then I started to search for the solution to click the stale element on the web page. After two days of thinking and googling, I got a solution.

    To access the stale element on the page, first, we need to focus the mouse over the particular section and perform click option

    EditReport1 = driver.find_element_by_id('internalTab1')
    ActionChains(driver).move_to_element(EditReport1).click(EditReport1).perform()
    

    move_to_element will move the mouse over the stale element which we need to access once we got our control on the element the click operation is successfully performed.

    This is worked for me. If anyone finds it working please comment your's as well which will help some other in future.

    Thank you

    0 讨论(0)
  • 2020-11-27 13:55

    For my python scripts, on quite simple pages, all above mentioned solutions didn't work. I found here -> https://www.softwaretestingmaterial.com/stale-element-reference-exception-selenium-webdriver/ the simplest way for my problem. It's just refreshing before clicking.

    driver.refresh()
    driver.find_element_by_id('normal').click()
    

    Note: I'm using driver.implicitly_wait(5) instead of explicit waits but it works in both options.

    0 讨论(0)
提交回复
热议问题