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后再进行元素定位:
- 获取Shadow Root:先定位包含Shadow Root的宿主元素,再通过
execute_script获取其Shadow Root对象 - 在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
相关产品推荐
相关产品推荐

