Rock
Rock

Reputation: 115

Not able to click on link in <li> elements list python code

Please Help!! I want to click on all main menu links for this i have written following code:

 html_list = self.driver.find_element_by_xpath("//*[@id='main-navigation']/ul")
 items = html_list.find_elements_by_tag_name("li")
        for item in items:
            item.click()
            time.sleep(20)

but it clicked on first menu option Brands and then it failed and gave following error:

   exception_class = ErrorInResponseException
        if status in ErrorCode.NO_SUCH_ELEMENT:
            exception_class = NoSuchElementException
        elif status in ErrorCode.NO_SUCH_FRAME:
            exception_class = NoSuchFrameException
        elif status in ErrorCode.NO_SUCH_WINDOW:
            exception_class = NoSuchWindowException
        elif status in ErrorCode.STALE_ELEMENT_REFERENCE:
            exception_class = StaleElementReferenceException
        elif status in ErrorCode.ELEMENT_NOT_VISIBLE:
            exception_class = ElementNotVisibleException
        elif status in ErrorCode.INVALID_ELEMENT_STATE:
            exception_class = InvalidElementStateException
E       selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

I am attaching screenshot of the webpage on which I am performing this action.

enter image description here

Upvotes: 1

Views: 96

Answers (2)

PDHide
PDHide

Reputation: 19979

html_list = WebDriverWait(driver, 10).until(
    EC.presence_of_all_elements_located((By.XPATH, "//*[@id = 'main-navigation']//li[.//a[not(@data-webtrekk-link-id='header.subnav')]]")))
for i in range(len(html_list)):
    time.sleep(3)
    html_list = WebDriverWait(driver, 10).until(
    EC.presence_of_all_elements_located((By.XPATH, "//*[@id = 'main-navigation']//li[.//a[not(@data-webtrekk-link-id='header.subnav')]]")))
    html_list[i].click()

there are many invisible elements , you should use the xpath locator as mentioned to find the element uniquely.

we are using time.sleep because presenceofallelement doesn't wait for all elements but for only first element

Difference between presenceOfElementLocated() and presenceOfAllElementsLocatedBy() is Selenium

Upvotes: 1

ble
ble

Reputation: 287

When you click on element from items, it changes in DOM making it impossible to continue to iterate through items because of StaleElementReference. Inspect elements to see how the structure changes.

I would suggest iterating by index instead of elements

html_list = self.driver.find_element_by_xpath("//*[@id='main-navigation']/ul")
items = html_list.find_elements_by_tag_name("li")
for i, _j in enumerate(items, start=1):
    self.driver.find_element_by_xpath("(//*[@id='main-navigation']/ul/li)[{}]".format(i))
    time.sleep(20)

Upvotes: 1

Related Questions