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

Python Selenium访问嵌套Shadow DOM树遇无效定位器错误求助

解决Adobe Express背景移除工具中深度嵌套Shadow DOM的元素定位问题

问题概述

在定位Adobe Express背景移除工具中的file-input元素时,由于目标元素处于多层嵌套的Shadow DOM结构中,使用原生Selenium逐层定位的方式触发InvalidArgumentException错误,报错信息如下:

selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: invalid locator

目标元素的层级结构为:

-tag sp-theme
  -id quick-task-container
    -tag cclqt-remove-background
       -SHADOW DOM
         -tag sp-theme
           -tag cclqt-workspace
             -tag cclqt-image-upload
               -SHADOW DOM
                 -class cclqt-file-upload__container 
                   -目标元素ID为'file-input'

错误原因

直接通过shadow_root.find_element()调用时,可能因以下原因导致定位器失效:

  • Selenium版本兼容性问题:部分旧版本Selenium对Shadow DOM的原生支持存在缺陷
  • 元素未完全加载:未等待元素渲染完成就执行定位操作
  • 多层Shadow DOM嵌套下,原生方法的链式调用容易出现上下文丢失

解决方案

方案1:使用JavaScript递归遍历Shadow DOM(推荐)

JavaScript可直接访问Shadow DOM结构,递归遍历所有层级能高效定位目标元素,避免手动逐层定位的繁琐:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://express.adobe.com/tools/remove-background")

# 设置隐式等待,确保页面元素加载完成
driver.implicitly_wait(10)

# 执行JS脚本递归查找嵌套Shadow DOM中的file-input元素
file_input = driver.execute_script("""
function findElementInShadowDOM(root, selector) {
    // 先在当前根节点查找
    let element = root.querySelector(selector);
    if (element) return element;
    // 遍历所有子元素的Shadow DOM
    const children = Array.from(root.querySelectorAll('*'));
    for (let child of children) {
        if (child.shadowRoot) {
            const found = findElementInShadowDOM(child.shadowRoot, selector);
            if (found) return found;
        }
    }
    return null;
}
// 从document根节点开始查找,目标选择器为#file-input
return findElementInShadowDOM(document, '#file-input');
""")

# 验证并使用元素
if file_input:
    print("成功定位file-input元素")
    # 执行上传操作:file_input.send_keys("本地图片路径")
else:
    print("未找到目标元素")

driver.quit()

方案2:修正原生Selenium逐层定位逻辑

若坚持使用原生Selenium方法,需添加显式等待确保每个元素加载完成,同时严格遵循层级结构:

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

driver = webdriver.Chrome()
driver.get("https://express.adobe.com/tools/remove-background")
wait = WebDriverWait(driver, 15)  # 设置15秒显式等待超时

# 逐层定位元素及Shadow DOM
sptheme = wait.until(EC.presence_of_element_located((By.TAG_NAME, "sp-theme")))
container = sptheme.find_element(By.ID, "quick-task-container")
cclqt_remove_bg = wait.until(EC.presence_of_element_located((By.TAG_NAME, "cclqt-remove-background")))
shadow_root1 = cclqt_remove_bg.shadow_root

# 从第一个Shadow DOM中定位元素
sptheme2 = shadow_root1.find_element(By.TAG_NAME, "sp-theme")
workspace = sptheme2.find_element(By.TAG_NAME, "cclqt-workspace")
image_upload = workspace.find_element(By.TAG_NAME, "cclqt-image-upload")
shadow_root2 = image_upload.shadow_root

# 最终定位目标元素
file_input = shadow_root2.find_element(By.ID, "file-input")

print("成功定位file-input元素")
driver.quit()

注意事项

  • 确保使用最新版本的Selenium和浏览器驱动,以获得更好的Shadow DOM支持
  • 若页面有动态加载逻辑,需根据实际情况调整等待时间或添加更多显式等待条件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:37:51