Python Selenium中return arguments[0].shadowRoot无效时定位Shadow DOM元素
解决Selenium 3中Shadow DOM内元素点击问题
问题核心原因
你使用的Selenium 3.141.0版本对Shadow DOM支持有限:通过execute_script获取的shadowRoot会返回一个序列化字典(而非WebElement对象),因此无法直接调用find_element方法,这是触发AttributeError的根本原因。另外,你用By.CLASS_NAME传入多类名(sc-dcJsrY jLOXfK)也是错误用法——CLASS_NAME仅支持单个类名,多类名需用CSS选择器处理。
解决方案
方案1:升级到Selenium 4+(推荐)
Selenium 4原生支持Shadow DOM操作,代码更简洁直观,无需依赖JavaScript:
# Python version 3.10.9 # selenium version 4.x+ from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep url = "https://www.cottages.com/search?adult=2&child=0&infant=0&pets=0&range=3&nights=7&accommodationType=cottages&start=29-12-2023&page=1&sort=priceasc®ionId=21996®ionName=South+West+England" # Selenium 4+无需手动指定executable_path(自动管理驱动) driver = webdriver.Chrome() driver.get(url) sleep(5) driver.implicitly_wait(5) # 定位Shadow DOM宿主元素 host = driver.find_element(By.XPATH, "/html/body/div[7]") # 直接获取shadow_root(Selenium 4原生属性) shadow_root = host.shadow_root # 用CSS选择器定位多类名按钮并点击 accept_btn = shadow_root.find_element(By.CSS_SELECTOR, '.sc-dcJsrY.jLOXfK') accept_btn.click()
方案2:Selenium 3下用JavaScript完成操作
若暂时无法升级版本,可直接在execute_script中完成Shadow DOM内元素的查找与点击,绕过Python层面的对象限制:
# Python version 3.10.9 # selenium version 3.141.0 from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep url = "https://www.cottages.com/search?adult=2&child=0&infant=0&pets=0&range=3&nights=7&accommodationType=cottages&start=29-12-2023&page=1&sort=priceasc®ionId=21996®ionName=South+West+England" driver = webdriver.Chrome(executable_path=r"C:/xxx/chromedriver-win64/chromedriver.exe") driver.get(url) sleep(5) driver.implicitly_wait(5) # 用JavaScript一次性完成定位与点击 driver.execute_script(""" // 找到Shadow DOM宿主元素 const host = document.querySelector('body > div:nth-child(7)'); if (!host) return; // 获取Shadow Root const shadowRoot = host.shadowRoot; if (!shadowRoot) return; // 定位按钮并执行点击 const acceptBtn = shadowRoot.querySelector('.sc-dcJsrY.jLOXfK'); if (acceptBtn) acceptBtn.click(); """)
关键注意事项
- 处理多类名元素时,必须用
By.CSS_SELECTOR,格式为.类名1.类名2,不能用By.CLASS_NAME - Selenium 3对Shadow DOM的支持存在先天缺陷,优先推荐升级到Selenium 4+版本
内容的提问来源于stack exchange,提问作者Dee G
相关产品推荐
相关产品推荐

