如何用Python的Selenium处理Shadow Root并在Adobe快速动作上传文件?
Adobe快速动作网站文件上传问题
我想在https://quick-actions.express.adobe.com/remove-background实现文件上传,执行以下代码时出现错误:
driver.get("https://quick-actions.express.adobe.com/remove-background") WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.TAG_NAME, "body"))) shadow_host = driver.find_element(By.TAG_NAME, "qa-standalone-app") shadow_root = shadow_host.shadow_root file_input = shadow_root.find_element(By.TAG_NAME, "input")
错误信息:selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: invalid locator
尝试直接定位文件输入框也失败:
file_input = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, '//input[@type="file"]')) ) file_input.send_keys(file_path)
尝试多层Shadow Root定位时,在第四步失败:
shadow_root1 = driver.find_element(By.CSS_SELECTOR, "qa-standalone-app").shadow_root shadow_root2 = shadow_root1.find_element(By.CSS_SELECTOR, "standalone-quick-action").shadow_root shadow_root3 = shadow_root2.find_element(By.CSS_SELECTOR, "qa-app-root").shadow_root shadow_root4 = shadow_root3.find_element(By.TAG_NAME, "qa-app").shadow_root # 此处失败 shadow_root5 = shadow_root4.find_element(By.CSS_SELECTOR, "qa-remove-background-editor").shadow_root shadow_root6 = shadow_root5.find_element(By.CSS_SELECTOR, "qa-workspace").shadow_root shadow_root7 = shadow_root6.find_element(By.CSS_SELECTOR, "qa-file-upload").shadow_root
补充页面元素结构截图:
可行解决方案
方法1:用JavaScript穿透多层Shadow DOM定位
该网站嵌套多层Shadow DOM,常规Selenium定位容易踩坑,直接通过执行JS遍历所有Shadow Root找到文件输入框:
driver.get("https://quick-actions.express.adobe.com/remove-background") # 等待页面完全加载 WebDriverWait(driver, 30).until(lambda d: d.execute_script('return document.readyState') == 'complete') # 执行JS查找file input file_input = driver.execute_script(""" function findFileInput(root) { const input = root.querySelector('input[type="file"]'); if (input) return input; // 遍历所有带shadow root的元素 const shadowHosts = root.querySelectorAll('*'); for (const host of shadowHosts) { if (host.shadowRoot) { const result = findFileInput(host.shadowRoot); if (result) return result; } } return null; } return findFileInput(document); """) # 上传文件 file_input.send_keys("你的本地文件绝对路径")
方法2:修正多层Shadow Root定位逻辑
之前定位失败大概率是元素未加载完全或选择器使用不当,给每一步添加等待确保元素就绪:
from selenium.webdriver.support import expected_conditions as EC driver.get("https://quick-actions.express.adobe.com/remove-background") # 第一层Shadow Root shadow_host1 = WebDriverWait(driver, 20).until( EC.presence_of_element_located((By.CSS_SELECTOR, "qa-standalone-app")) ) shadow_root1 = shadow_host1.shadow_root # 第二层Shadow Root shadow_host2 = WebDriverWait(shadow_root1, 20).until( EC.presence_of_element_located((By.CSS_SELECTOR, "standalone-quick-action")) ) shadow_root2 = shadow_host2.shadow_root # 第三层Shadow Root shadow_host3 = WebDriverWait(shadow_root2, 20).until( EC.presence_of_element_located((By.CSS_SELECTOR, "qa-app-root")) ) shadow_root3 = shadow_host3.shadow_root # 第四层Shadow Root(改用CSS_SELECTOR更准确) shadow_host4 = WebDriverWait(shadow_root3, 20).until( EC.presence_of_element_located((By.CSS_SELECTOR, "qa-app")) ) shadow_root4 = shadow_host4.shadow_root # 第五层Shadow Root shadow_host5 = WebDriverWait(shadow_root4, 20).until( EC.presence_of_element_located((By.CSS_SELECTOR, "qa-remove-background-editor")) ) shadow_root5 = shadow_host5.shadow_root # 第六层Shadow Root shadow_host6 = WebDriverWait(shadow_root5, 20).until( EC.presence_of_element_located((By.CSS_SELECTOR, "qa-workspace")) ) shadow_root6 = shadow_host6.shadow_root # 第七层Shadow Root shadow_host7 = WebDriverWait(shadow_root6, 20).until( EC.presence_of_element_located((By.CSS_SELECTOR, "qa-file-upload")) ) shadow_root7 = shadow_host7.shadow_root # 定位文件输入框并上传 file_input = WebDriverWait(shadow_root7, 20).until( EC.presence_of_element_located((By.CSS_SELECTOR, 'input[type="file"]')) ) file_input.send_keys("你的本地文件绝对路径")
注意点
- 确保使用Selenium 4及以上版本,低版本不支持Shadow DOM操作
- 代码中的文件路径必须是本地绝对路径,不能用相对路径
- 若页面加载慢,可适当延长等待时间(比如把20改成30)
内容的提问来源于stack exchange,提问作者LA_
相关产品推荐
相关产品推荐

