如何使用Selenium Python定位并操作嵌套Shadow DOM元素?
问题分析与修复方案
报错原因
你的代码核心问题是没有从上层Shadow DOM的根节点(shadowRoot)中查找子元素,而是直接用driver.find_element去定位,而这些元素都嵌套在之前的Shadow DOM内部,主DOM无法直接访问。另外,部分节点(比如.toolbar-top、.toolbar-bottom)本身没有Shadow DOM,你错误地尝试获取它们的shadowRoot,这也会导致无效操作。
修正后的代码
from selenium import webdriver from selenium.webdriver.common.by import By url = "https://books-pwakit.appspot.com/" driver = webdriver.Chrome() driver.get(url) # 获取最外层book-app的shadowRoot shadow_host1 = driver.find_element(By.CSS_SELECTOR, "book-app[apptitle='BOOKS']") shadow_root1 = driver.execute_script('return arguments[0].shadowRoot', shadow_host1) # 在book-app的shadowRoot里找app-header,并获取它的shadowRoot shadow_host2 = shadow_root1.find_element(By.CSS_SELECTOR, "app-header[effects='waterfall']") shadow_root2 = driver.execute_script('return arguments[0].shadowRoot', shadow_host2) # 在app-header的shadowRoot里找搜索框所在的toolbar-bottom容器 toolbar_bottom = shadow_root2.find_element(By.CSS_SELECTOR, '.toolbar-bottom') # 在toolbar-bottom里找book-input-decorator,并获取它的shadowRoot shadow_host5 = toolbar_bottom.find_element(By.CSS_SELECTOR, 'book-input-decorator') shadow_root5 = driver.execute_script('return arguments[0].shadowRoot', shadow_host5) # 在book-input-decorator的shadowRoot里找到输入框并输入内容 search_input = shadow_root5.find_element(By.CSS_SELECTOR, '#input') search_input.send_keys("Twilight")
关键说明
- 所有嵌套在Shadow DOM内的元素,必须从父级的shadowRoot中调用
find_element来定位,不能直接用全局的driver.find_element。 .toolbar-top、.toolbar-bottom这类普通DOM节点没有自己的Shadow DOM,不需要调用execute_script获取shadowRoot,直接在父级shadowRoot里定位即可。- 每次进入新的Shadow DOM层级,都要通过
execute_script('return arguments[0].shadowRoot', host_element)来获取该节点的Shadow根,才能访问内部元素。
内容的提问来源于stack exchange,提问作者Tanvir Ahmed
相关产品推荐
相关产品推荐

