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

Selenium操作迪士尼餐厅页面遭遇NoSuchElementException问题求助

问题:无法定位迪士尼餐厅预订页面的时间下拉框元素

我正在自动化操作迪士尼加拿大官网的餐厅预订页面,使用Selenium Webdriver时,日期选择器已成功设置目标日期,但时间字段的下拉框完全无法定位——既不能点击,也抓取不到任何内容,尝试标签、ID、XPath等多种定位方式,均返回NoSuchElementException或空列表。

我的代码

url = 'https://disneyland.disney.go.com/en-ca/dining/'
driver.get(url)
driver.find_element(By.ID, "custom-dropdown-options-list")

报错信息

---------------------------------------------------------------------------
NoSuchElementException                    Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_15484\3697586215.py in <module>
----> 1 driver.find_element(By.ID, "custom-dropdown-options-list")

~\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py in find_element(self, by, value)
    828             value = f'[name="{value}"]'
    829 
--> 830         return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]
    831 
    832     def find_elements(self, by=By.ID, value: Optional[str] = None) -> List[WebElement]:

~\anaconda3\lib\site-packages\selenium\webdriver\remote\webdriver.py in execute(self, driver_command, params)
    438         response = self.command_executor.execute(driver_command, params)
    439         if response:
--> 440             self.error_handler.check_response(response)
    441             response["value"] = self._unwrap_value(response.get("value", None))
    442             return response

~\anaconda3\lib\site-packages\selenium\webdriver\remote\errorhandler.py in check_response(self, response)
    243                 alert_text = value["alert"].get("text")
    244             raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
--> 245         raise exception_class(message, screen, stacktrace)

NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id=\"custom-dropdown-options-list\"]"}
  (Session info: chrome=110.0.5481.97)
Stacktrace:
Backtrace:
    (No symbol) [0x004F37D3]
    (No symbol) [0x00488B81]
    (No symbol) [0x0038B36D]
    (No symbol) [0x003BD382]
    (No symbol) [0x003BD4BB]
    (No symbol) [0x003F3302]
    (No symbol) [0x003DB464]
    (No symbol) [0x003F1215]
    (No symbol) [0x003DB216]
    (No symbol) [0x003B0D97]
    (No symbol) [0x003B253D]
    GetHandleVerifier [0x0076ABF2+2510930]
    GetHandleVerifier [0x00798EC1+2700065]
    GetHandleVerifier [0x0079C86C+2714828]
    GetHandleVerifier [0x005A3480+645344]
    (No symbol) [0x00490FD2]
    (No symbol) [0x00496C68]
    (No symbol) [0x00496D4B]
    (No symbol) [0x004A0D6B]
    BaseThreadInitThunk [0x76FF00F9+25]
    RtlGetAppContainerNamedObjectPath [0x77B57BBE+286]
    RtlGetAppContainerNamedObjectPath [0x77B57B8E+238]

尝试定位下拉按钮的XPath时,同样报错:

driver.find_element(By.XPATH, '//*[@id="custom-dropdown-button"]/div[2]/i')

经排查,目标元素位于页面的#shadow-root下,这是导致Selenium无法直接定位的核心原因。


解决方法

Selenium默认无法直接访问Shadow DOM内的元素,需要通过JavaScript获取Shadow Root后再进行元素定位:

  1. 获取Shadow Root:先定位包含Shadow Root的宿主元素,再通过execute_script获取其Shadow Root对象
  2. 在Shadow Root内定位元素:通过Shadow Root对象查找目标下拉框或按钮

示例代码:

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

url = 'https://disneyland.disney.go.com/en-ca/dining/'
driver = webdriver.Chrome()
driver.get(url)

# 显式等待宿主元素加载完成(需替换为实际页面的宿主元素选择器)
host_element = WebDriverWait(driver, 15).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, 'your-host-element-selector'))
)

# 获取Shadow Root
shadow_root = driver.execute_script('return arguments[0].shadowRoot', host_element)

# 在Shadow Root内点击时间下拉框按钮
time_dropdown_button = shadow_root.find_element(By.ID, 'custom-dropdown-button')
time_dropdown_button.click()

# 定位并选择目标时间选项
time_options = shadow_root.find_element(By.ID, 'custom-dropdown-options-list')
target_time = time_options.find_element(By.XPATH, './/div[text()="12:00 PM"]')
target_time.click()

driver.quit()

注意:需替换your-host-element-selector为实际页面中包含Shadow Root的宿主元素的CSS选择器(可通过浏览器开发者工具查看页面结构获取)。显式等待能有效避免页面未加载完成导致的定位失败问题,比隐式等待更稳定。


内容的提问来源于stack exchange,提问作者Muhammad Daniyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:15:43