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