如何使用Python Selenium定位并点击嵌套Shadow DOM中的下载按钮?
解决多层Shadow DOM中Selenium点击下载按钮的问题
针对多层嵌套Shadow DOM里的下载按钮,你可以试试以下几种更可靠的写法:
方法一:递归遍历Shadow DOM查找目标按钮
写个JS函数递归遍历所有Shadow DOM节点,不用硬写固定嵌套路径,灵活性更高:
# 执行JS脚本直接找到并点击按钮 driver.execute_script(""" function findElementInShadowDom(element, selector) { let result = element.querySelector(selector); if (result) return result; for (let child of element.children) { if (child.shadowRoot) { result = findElementInShadowDom(child.shadowRoot, selector); if (result) return result; } } return null; } const downloadBtn = findElementInShadowDom(document, 'button[aria-label="Download"]'); if (downloadBtn) downloadBtn.click(); """)
方法二:优化原有链式写法,加入等待逻辑
原代码容易因元素未加载完成导致查询失败,加上显式等待确保每个节点存在后再继续:
from selenium.webdriver.support.ui import WebDriverWait # 等待最外层自定义元素加载完成 WebDriverWait(driver, 10).until( lambda d: d.execute_script('return document.querySelector("body > tii-ai-writing-app")') ) # 分步查询每个Shadow DOM节点,避免一步出错全失败 downloadBtn = driver.execute_script(""" let app = document.querySelector("body > tii-ai-writing-app"); if (!app.shadowRoot) return null; let router = app.shadowRoot.querySelector("tii-router"); if (!router.shadowRoot) return null; let home = router.shadowRoot.querySelector("aiwa-home"); if (!home.shadowRoot) return null; let downloadMfe = home.shadowRoot.querySelector("tii-sws-submission-workspace > tii-sws-header > tii-sws-download-btn-mfe"); if (!downloadMfe.shadowRoot) return null; let headerBtn = downloadMfe.shadowRoot.querySelector("#download-popover > tii-sws-header-btn"); if (!headerBtn.shadowRoot) return null; let tdlBtn = headerBtn.shadowRoot.querySelector("tdl-button"); if (!tdlBtn.shadowRoot) return null; return tdlBtn.shadowRoot.querySelector('button[aria-label="Download"]'); """) if downloadBtn: driver.execute_script('arguments[0].click();', downloadBtn)
方法三:直接在JS内完成点击(最简洁)
不用返回元素到Python上下文,直接在JS里完成查找和点击,减少跨上下文的潜在问题:
driver.execute_script(""" document.querySelector("body > tii-ai-writing-app").shadowRoot .querySelector("tii-router").shadowRoot .querySelector("aiwa-home").shadowRoot .querySelector("tii-sws-submission-workspace > tii-sws-header > tii-sws-download-btn-mfe").shadowRoot .querySelector("#download-popover > tii-sws-header-btn").shadowRoot .querySelector("tdl-button").shadowRoot .querySelector('button[aria-label="Download"]').click(); """)
如果运行时报错,优先检查是不是元素加载延迟导致的,给关键节点加上等待逻辑就能解决大部分问题。
内容的提问来源于stack exchange,提问作者saffin
相关产品推荐
相关产品推荐

