问题描述
我正在使用Selenium(Python)自动执行网页。我正在尝试从#shadow-root(用户代理)下的输入字段中获取文本。 我使用的Xpath:
driver.find_element_by_xpath("**//*/p-calendar/span/input**").text
未返回任何内容。 附上我的DOM元素的屏幕截图。 要求:要从影子根获取文本:01:01
解决方法
根据@hayatoito
(影子DOM的创建者)comment:
引入封闭的阴影树的最初动机是AFAIK
"Never allow an access to a node in a closed shadow tree,via any APIs,from outside"
。这样一来,我们就无法访问Blink中<video>
元素中使用的内部隐藏阴影树中的节点。
实际上,我以这种方式设计了一个封闭的影子树。如果可以访问封闭的影子树中的节点,则应将其视为规范的错误。
我认为拥有一个允许访问Chrome应用或扩展程序层的API完全可以。 但是,对于普通的Web应用程序,我认为当前协议为
"Never allow it"
。
如果我们允许,那就意味着我们不需要封闭的影子树。我认为只有一棵开放的影子树就足够了。
Furhter @Supersharp
在讨论How to get element in user-agent shadow root with JavaScript?中他自己的回答下面的评论中提到:
#shadow-root (user-agent)
是浏览器供应商的本机实现,因此没有文档记录,并且将永远无法访问。根据规范,只有打开的Shadow DOM是
WebDriver透视图
最近,@ AutomatedTester [Mozilla公司首席培根官David Burns]发起了关于WebDriver - Testability of web components
的讨论目前 Selenium Team 已开放,可以接受对它的请求请求。
参考
您可以在以下位置找到几个相关的详细讨论:
Outro
在这里您可以找到有关How to automate shadow DOM elements using selenium?的相关讨论
,您可以使用driver.execute_script
注入返回ShadowRoot的JavaScript代码,然后使用find_element
获取您要查找的影子根的children元素。
input_shadow = driver.execute_script('''return document.querySelector("$1").shadowRoot''')
div_text = inputShadow.find_element_by_tag_name("div").text
$ 1-Your element's identifier or selector
。
如果您热衷于使用xpath查找元素
input_shadow = driver.execute_script('''return $x(\"//*/p-calendar/span/input\")[0]''')
div_text = inputShadow.find_element_by_tag_name("div").text