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

使用Python Selenium抓取Shadow Root元素时遇AttributeError问题求助

解决Selenium操作Shadow DOM时的AttributeError问题

问题背景

我在一个小型项目中尝试抓取网站数据,所需数据隐藏在HTML的#Shadow-root标签下。使用Selenium编写了如下代码:

def expand_shadow_element(element):
  shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
  return shadow_root

url = "https://new.abb.com/products/SK615502-D"

#Initializing the webdriver
options = webdriver.ChromeOptions()

driver = webdriver.Chrome(executable_path="/Users/ritchevy/Desktop/scraping-glassdoor/chromedriver", options=options)
timeout = 10
wait = WebDriverWait(driver, timeout)

driver.set_window_size(1120, 1000)
driver.get(url)

root1 = driver.find_element(By.CSS_SELECTOR,"pis-products-details-attribute-groups")
shadow_root1 = expand_shadow_element(root1)
shadow_container_root = shadow_root1.find_element(By.CSS_SELECTOR,"div")

执行时触发错误:

---> 35 shadow_container_root = shadow_root1.find_element(By.CSS_SELECTOR,"div")
     36 

AttributeError: 'dict' object has no attribute 'find_element'

问题原因

新版Selenium(尤其是v4+)通过execute_script获取shadowRoot时,返回的是字典格式的元素元数据,而非可直接调用find_element方法的WebElement对象,因此触发属性不存在的报错。

解决方案

方法1:使用Selenium原生shadow_root属性(推荐)

Selenium 4.0及以上版本已为WebElement对象内置shadow_root属性,无需通过JS脚本获取,直接调用即可得到可操作的Shadow Root对象:

def expand_shadow_element(element):
    return element.shadow_root  # 直接返回原生Shadow Root对象

# 后续代码保持原有逻辑
root1 = driver.find_element(By.CSS_SELECTOR,"pis-products-details-attribute-groups")
shadow_root1 = expand_shadow_element(root1)
shadow_container_root = shadow_root1.find_element(By.CSS_SELECTOR,"div")

方法2:将字典转换为WebElement对象

如果必须保留JS脚本的方式,可以通过driver.create_web_element方法把返回的字典转换为可操作的WebElement:

def expand_shadow_element(element):
    shadow_root_dict = driver.execute_script('return arguments[0].shadowRoot', element)
    # 提取字典中的元素ID并转换为WebElement
    return driver.create_web_element(shadow_root_dict['element-6066-11e4-a52e-4f735466cecf'])

# 调用逻辑不变
root1 = driver.find_element(By.CSS_SELECTOR,"pis-products-details-attribute-groups")
shadow_root1 = expand_shadow_element(root1)
shadow_container_root = shadow_root1.find_element(By.CSS_SELECTOR,"div")

额外建议

  • 检查并升级Selenium版本:通过pip show selenium查看版本,若低于4.0执行pip install --upgrade selenium
  • 结合显式等待提升稳定性:操作Shadow DOM内元素时,用WebDriverWait等待元素加载完成,避免超时或未找到元素的问题:
from selenium.webdriver.support import expected_conditions as EC

shadow_root1 = expand_shadow_element(root1)
shadow_container_root = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div")))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 11:50:09