Xpath 表达式可以访问 shadow-root 元素吗?

Can Xpath expressions access shadow-root elements?

目前我正在抓取文章新闻网站,在获取其主要内容的过程中,我 运行 发现其中很多网站都嵌入了如下推文:

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

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

即使网络抓取工具支持 Shadow DOM,也根本不支持 XPath。仅在某种程度上支持选择器,如 CSS Scoping spec.

中所述

使用不适用于阴影 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