Xpath表达式可以访问阴影根元素吗?

时间:2018-04-10 22:14:23

标签: xpath web-scraping scrapy shadow-dom

目前我正在抓文章新闻网站,在获取其主要内容的过程中,我遇到了很多人在其中嵌入推文的问题:

enter image description here

我使用带有XPath helper(chrome addon)的XPath表达式来测试我是否可以获取内容,然后将此表达式添加到scrapy python中,但使用#shadow-root元素内的元素似乎超出DOM的范围,我正在寻找一种方法来获取这些类型的元素内容,最好是使用XPath。

2 个答案:

答案 0 :(得分:1)

大多数网络抓取工具(包括Scrapy)都不支持Shadow DOM,因此您根本无法访问阴影树中的元素。

即使Web刮刀确实支持Shadow DOM,也根本不支持XPath。在CSS Scoping spec

中记录的仅在某种程度上支持选择器

答案 1 :(得分:1)

使用与影子DOM API不兼容的工具来抓取包含影子DOM的页面的一种方法是递归地遍历影子DOM元素,并用其HTML代码替换它们:

// Returns HTML of given shadow DOM.
const getShadowDomHtml = (shadowRoot) => {
    let shadowHTML = '';
    for (let el of shadowRoot.childNodes) {
        shadowHTML += el.nodeValue || el.outerHTML;
    }
    return shadowHTML;
};

// Recursively replaces shadow DOMs with their HTML.
const replaceShadowDomsWithHtml = (rootElement) => {
    for (let el of rootElement.querySelectorAll('*')) {
        if (el.shadowRoot) {
            replaceShadowDomsWithHtml(el.shadowRoot)
            el.innerHTML += getShadowDomHtml(el.shadowRoot);
        }
    }
};

replaceShadowDomsWithHtml(document.body);

如果您使用完整的浏览器(Chrome和Puppeteer,PhantomJS等)进行抓取,则只需将此脚本插入页面即可。重要的是在呈现整个页面之后执行此操作,因为这可能会破坏阴影DOM组件的JS代码。

查看我撰写的有关该主题的全文:https://kb.apify.com/tips-and-tricks/how-to-scrape-pages-with-shadow-dom