有没有办法在Selenium的阴影根中获取元素信息?

时间:2018-02-19 23:09:32

标签: java selenium web-crawler shadow-dom

我正试图从一个包含java和selenium的网站上获取一些信息。但是,由于阴影根我无法访问任何web元素。当我尝试获取html时,它返回空数组。有没有办法达到shadow-root里面的信息,还是不可能? html structure of the website

2 个答案:

答案 0 :(得分:1)

您可以尝试使用JavascriptExecutor查找shadow-root中的元素。

WebElement rootElement = (WebElement) ((JavascriptExecutor)driver).executeScript("return arguments[0].shadowRoot", PreRootElement);

详情请参阅:http://www.seleniumeasy.com/selenium-tutorials/accessing-shadow-dom-elements-with-webdriver

答案 1 :(得分:0)

Mavni的答案为我解决了这个问题,但是作为一种改进,我希望能够使用By作为定位符(例如,等待ExpectedCondition)。

public class ByShadowRoot extends By {

    @Override
    public WebElement findElement( SearchContext context ) {

        RemoteWebElement element = ( RemoteWebElement ) context;
        JavascriptExecutor driver = ( JavascriptExecutor ) element.getWrappedDriver();
        return ( WebElement ) driver.executeScript( "return arguments[0].shadowRoot" , element );
    }

    @Override
    public List<WebElement> findElements( SearchContext context ) {

        WebElement element = findElement( context );
        return element != null ? Collections.singletonList( element ) : Collections.emptyList();
    }

    @Override
    public String toString() {

        return "By#shadow-root";
    }
}

然后像这样使用它(此示例用于等待组合框在Vaadin Flow中弹出):

ByShadowRoot byShadowRoot = new ByShadowRoot();
By comboBoxItem = new ByChained( By.id( "overlay" ) , byShadowRoot , By.id( "content" ) , byShadowRoot , By.id( "selector" ) ,
    By.tagName( "vaadin-combo-box-item" ) );

({ByChained在selenium-support.jar中)

如果By.tagName()byShadowRoot紧接在WebDriverException: unknown error: b.getElementsByTagName is not a function之后,则有一个微妙的问题。我认为这是因为#shadow-root只是DOM中的文档片段,而不是文档元素。