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

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&regionId=21996&regionName=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&regionId=21996&regionName=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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:00:22