我正在研究一个广泛使用阴影dom的自动化项目。所以每次使用execute_script函数访问shadow root
例如。
root = driver.execute_script('return document.querySelector(".flex.vertical.layout").shadowRoot')
然后使用root访问其中的元素。由于我们在很多层面都有影子根源,这让我很烦恼。是否存在比这更好的解决方案来访问阴影根中的元素?
我使用的是Chrome 2.20驱动程序。
答案 0 :(得分:4)
通过谷歌搜索我发现了另一个解决这个问题的方法 - 使用" / deep / combinator"。
例如,我能够通过
访问所有阴影根元素driver.find_elements_by_css_selector('主体/深/ .layout.horizontal.center&#39)
这将可以访问具有复合类名称的元素"布局水平中心"无论它有多少影子根。
但这只适用于Chrome驱动程序,我看到了注释" / deep /"是一种弃用的方法。
答案 1 :(得分:3)
关于Shadow DOM,WebDriver规范仍然是doesn't have anything specific to say。
也不是Selenium project pages - 这是可以理解的,因为它们严格遵循规范。然而,存在some low-level code。
因此,简短的回答是:不,目前在Selenium的WebDriver API或实施代码中,规范中没有特别的支持。
是的,该功能似乎存在于ChromeDriver 2.14中(作为Chrome的包装)。但是,据我所知,没有Selenium或WebDriver级别的绑定可以让你使用它。
但是有关更多详细信息和可能的解决方法,请参阅:Accessing Shadow DOM tree with Selenium,还有:Accessing elements in the shadow DOM,尤其是:Finding elements in the shadow DOM
答案 2 :(得分:2)
您可以编写扩展方法来操作IWebElement以扩展根目录,如下所示。
public static class SeleniumExtension
{
public static IWebElement ExpandRootElement(this IWebElement element, IWebDriver driver)
{
return (IWebElement)((IJavaScriptExecutor)driver)
.ExecuteScript("return arguments[0].shadowRoot", element);
}
}
您可以使用上面的扩展方法遍历元素层次结构以到达intrest元素。
By downloads_manager_ShadowDom= By.TagName("downloads-manager");
By downloadToolBarShadowDom = By.CssSelector("downloads-toolbar");
By toolBarElement = By.CssSelector("cr-toolbar");
IWebElement ToolBarElement = driver.FindElement(downloads_manager_ShadowDom).ExpandRootElement(driver)
.FindElement(downloadToolBarShadowDom).ExpandRootElement(driver)
.FindElement(toolBarElement);
答案 3 :(得分:0)
由于您经常使用可以创建函数,因此上面的内容变为:
plt.tick_params(axis='both', labelsize=20)
在结果元素上你可以放任何方法:
def select_shadow_element_by_css_selector(selector): running_script = 'return document.querySelector("%s").shadowRoot' % selector element = driver.execute_script(running_script) return element shadow_section = select_shadow_element_by_css_selector(".flex.vertical.layout") shadow_section.find_element_by_css(".flex")
要查找多个元素(这些方法将返回一个列表):
find_element_by_id find_element_by_name find_element_by_xpath find_element_by_link_text find_element_by_partial_link_text find_element_by_tag_name find_element_by_class_name find_element_by_css_selector
稍后修改:
有时阴影主机元素会隐藏阴影树,这就是为什么最好的方法是使用selenium选择器来查找阴影主机元素并注入脚本只是为了获取阴影根:
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
为了说明这一点,我刚刚在Chrome的下载页面添加了一个可测试的示例,单击搜索按钮需要打开3个嵌套的阴影根元素:
def expand_shadow_element(element):
shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
return shadow_root
#the above becomes
shadow_section = expand_shadow_element(find_element_by_tag_name("neon-animatable"))
shadow_section.find_element_by_css(".flex")
答案 4 :(得分:0)
不确定它适用于所有浏览器,但对我来说
::shadow
在chromedriver 2.38中工作正常。例如:
div::shadow div span::shadow a