0

I am trying to iterate through the drop down button on a website using the following code:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

def main():
    try:
        # url of the website where the data will be collected from
        url = "https://app.cpcbccr.com/ccr/#/caaqm-dashboard-all/caaqm-landing"

        # path to the browser on my computer
        browser = webdriver.Chrome()

        # access the website
        browser.get(url)
        time.sleep(30)
        browser.find_element(By.XPATH, '/html/body/app-root/app-caaqm-dashboard/div[1]/div/main/section/app-caaqm-landing/div[2]/div[1]/div[1]/div[1]').click()
        time.sleep(30)
        browser.switch_to.window(browser.window_handles[1])
        print("-------------------------------------")
        print(browser.current_url)
        print("-------------------------------------")

        # Locate the state_name element
        state_name = browser.find_element(By.XPATH, '/html/body/app-root/app-caaqm-dashboard/div[1]/div/main/section/app-caaqm-view-data/div/div/div[1]/div[1]/div/ng-select')

        # Check if the state_name element is inside an iframe
        if state_name.get_attribute("tagName").lower() == "iframe":
            # Switch to the iframe
            browser.switch_to.frame(state_name)

            # Locate the state_name element within the iframe
            state_name = browser.find_element(By.XPATH, 'your_xpath_here')

        # Click on the state_name element to expand the dropdown
        state_name.click()
        time.sleep(3)

        # Simulate keyboard interactions to loop over the options
        list_of_state_names = []
        state_name.send_keys(Keys.ARROW_DOWN)
        list_of_state_names.append(state_name.get_attribute("value"))
        state_name_count = 0
        while True:
            # Send an arrow down key to navigate to the next option
            state_name.send_keys(Keys.ARROW_DOWN)
            time.sleep(0.5)

            # Check if the selected option is the first option again, indicating we have looped through all the options
            if state_name.get_attribute("value") == list_of_state_names[0]:
                break

            # Get the current selected option text
            state_name_count += 1
            list_of_state_names[state_name_count] = state_name.get_attribute("value")
        for state in list_of_state_names:
            print(state)

        while (True):
            pass
    except Exception as exception:
        print("-------------------------------------")
        print(exception)
        print("-------------------------------------")
        raise(exception)
    

if __name__ == '__main__':
    main() 

However, I got an error from Command Prompt saying that the drop down I am working with is not interactable, which is not the case at all because I can use the arrow down key on the drop down manually. The code also worked just fine when I use Selenium's click() function.

I raised exception and Command Prompt says that the error is coming from the line of code that goes "state_name.send_keys(Keys.ARROW_DOWN)", but I can't really think of why a drop down that I could use the arrow down key on manually wouldn't let me do that with Selenium's simulated arrow down key.

Here is a screenshot of the website together with its "Inspect Element" window should it be helpful. The html code that corresponds to the drop down is in blue (https://i.stack.imgur.com/tJi8A.png)

I can't seem to figure out where this bug is coming from. Any help and support would be much appreciated!

  • After the "state_name" ng-select object is created, you call state_name.click(). is it really the state_name that you want to be the focus of the send_keys()? you may need to define another element to send the down arrow to. – Breaks Software Jun 28 '23 at 11:34

1 Answers1

0

To select the option with text Andhra Pradesh from the <select-dropdown> you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:

  • Using XPATH and contains():

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='placeholder']"))).click()
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[contains(., 'Andhra Pradesh')]"))).click()
    
  • Using XPATH and normalize-space():

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='placeholder']"))).click()
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[normalize-space()='Andhra Pradesh']"))).click()
    
  • Note: You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352