Search code examples
pythonselenium-webdriverxpath

Can't locate a clickable element by XPATH Selenium Python


I am trying to click on a drop-down menu and then a specific value within menu. I am working with the float range menu at https://buff.163.com/goods/769563?from=market#tab=buying&page_num=1. I've tried using the relative xpath from SelectorsHub and the paintwear_list id, but I keep getting this error:

selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable

Here is the code I am running:

floatRange = waitForItem(driver, By.XPATH, "(//div[@class='w-Select-Multi w-Select-scroll black float_range'])[2]", timeout=3)
    floatRange.click()

allBuyOrders = waitForItem(driver, By.XPATH, "//h6[@value='-1~-1']", timeout=3)
allBuyOrders.click()

I know the issue isn't that the element hasn't loaded in because I am using webdriverwait through the waitForItem call. Here is the waitForItem function:

def waitForItem(driver, selector_type, selector_value, timeout=20, logging=False):
    try:
        element = WebDriverWait(driver, timeout).until(
            EC.presence_of_element_located((selector_type, selector_value)))
    except selenium.common.exceptions.TimeoutException:
        if logging:
            print(
                f" > Timeout error: Element couldn't be located. ({selector_value})")
        return None
    return element

Here is the HTML: enter image description here

I need to click on the "Any" value in the drop-down.

Any ideas?

Thanks for any help


Solution

  • We cannot guess what is inside of the 'waitForItem' method/function.

    To select the option 'Any' on the provided website, you first need to expand the dropdown, ensure that it is expanded, and only then do the option selection.

    The 'ElementNotInteractableException' exception means that the element is present in the DOM, but the target element state is not reached yet, so you have to wait for a while.

    The following code sample works well for me:

    try:
        driver.get("https://buff.163.com/goods/769563?from=market#tab=buying&page_num=1")
    
        # open the dropdown
        wait.until(EC.element_to_be_clickable(
            (By.CSS_SELECTOR, "div#asset_tag-filter-buyOrder div#custom_paintwear_val"))
        ).click()
        wait.until(EC.visibility_of_element_located(
            (By.CSS_SELECTOR, "div#asset_tag-filter-buyOrder div#custom_paintwear_val.on"))
        )
    
        # select the 'Any' option
        wait.until(EC.element_to_be_clickable(
            (By.XPATH, "//div[@id='asset_tag-filter-buyOrder']//ul/li/h6[text()='Any']"))
        ).click()
    finally:
        driver.quit()
    

    ! EDIT !

    The following code, which utilizes your function, also works:

    def waitForItem(driver, selector_type, selector_value, timeout=20, logging=False):
        try:
            element = WebDriverWait(driver, timeout).until(
                EC.element_to_be_clickable((selector_type, selector_value)))
        except TimeoutException:
            if logging:
                print(
                    f" > Timeout error: Element couldn't be located. ({selector_value})")
            return None
        return element
    
    
    try:
        driver.get("https://buff.163.com/goods/769563?from=market#tab=buying&page_num=1")
    
        waitForItem(driver, By.CSS_SELECTOR, "div#asset_tag-filter-buyOrder div#custom_paintwear_val").click()
        waitForItem(driver, By.CSS_SELECTOR, "div#asset_tag-filter-buyOrder div#custom_paintwear_val.on")
        waitForItem(driver, By.XPATH, "//div[@id='asset_tag-filter-buyOrder']//ul/li/h6[text()='Any']").click()
    finally:
        driver.quit()