You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ng-select下拉框Selenium模拟箭头键报错Element not interactable

问题:Selenium操作下拉框提示Element not interactable,点击正常但send_keys失效

我尝试用以下代码遍历网站下拉框,代码中click()能正常展开下拉框,但执行state_name.send_keys(Keys.ARROW_DOWN)时命令提示符报错Element not interactable,手动用箭头键可以操作该下拉框,找不到问题根源。

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() 

解决方案

问题原因

你定位的是ng-select容器元素,点击展开下拉后,箭头键的实际作用对象是下拉列表里的选项元素,而非容器本身,所以向容器发送键盘事件会触发不可交互报错。

修正方案

直接定位下拉展开后的选项元素,遍历操作即可,无需模拟键盘:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

def main():
    try:
        url = "https://app.cpcbccr.com/ccr/#/caaqm-dashboard-all/caaqm-landing"
        browser = webdriver.Chrome()
        browser.get(url)
        
        # 等待页面加载,替换固定sleep为显式等待更可靠
        WebDriverWait(browser, 30).until(
            EC.element_to_be_clickable((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()
        
        # 等待新窗口打开并切换
        WebDriverWait(browser, 30).until(lambda d: len(d.window_handles) > 1)
        browser.switch_to.window(browser.window_handles[1])
        print("-------------------------------------")
        print(browser.current_url)
        print("-------------------------------------")

        # 定位ng-select容器并点击展开下拉
        state_select = WebDriverWait(browser, 10).until(
            EC.element_to_be_clickable((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'))
        )
        state_select.click()

        # 等待下拉选项加载完成,定位所有选项
        state_options = WebDriverWait(browser, 10).until(
            EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'ng-dropdown-panel .ng-option'))
        )

        # 遍历选项,获取文本并打印(如需选择可添加click())
        list_of_state_names = []
        for option in state_options:
            state_text = option.text
            list_of_state_names.append(state_text)
            print(state_text)
            # 如果需要选中当前选项,取消注释下面一行
            # option.click()
            # time.sleep(1)

        print("所有状态列表:", list_of_state_names)

        # 保持窗口打开,方便查看
        while True:
            pass
    except Exception as exception:
        print("-------------------------------------")
        print(exception)
        print("-------------------------------------")
        raise exception
    

if __name__ == '__main__':
    main() 

关键优化点

  • 用显式等待替换固定time.sleep(),提升代码稳定性,避免因页面加载慢导致的元素定位失败
  • 直接定位下拉选项元素,绕开键盘模拟的交互问题
  • 使用CSS选择器定位选项,比绝对XPATH更健壮,不易因页面结构变化失效

内容的提问来源于stack exchange,提问作者Nguyễn Văn Chiến

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 00:05:02