详细说明我的评论:
如果要呈现动态部分,则需要在 iframe 中加载内容。
这是必要的,因为XMLHttpRequest
只是获取页面的源代码,它不运行任何嵌入的脚本。
注意 X-Frame-Options 标头,
下一个解决方案仅在X-Frame-Options
未随响应发送时才有效。设置此响应标头时,页面不能嵌入到框架中。您必须删除此标头,如本答案所示。
并确保您在 iframe 上设置了沙盒属性以避免框架破坏。
您将在文档中插入一个<iframe>
包含本方内容的内容。在没有任何反制措施的情况下,这个第三方页面可以使用 替换顶部文档if (top !== window) {top.location = location.href;}
,也称为框架破坏。
从外观上看,您的脚本被用作内容脚本。插入一个框架,并在该框架内使用相同的内容脚本来获取所需的信息。
manifest.json
...
"content_scripts": [{
"js": ["contentscript.js"],
"all_frames": true,
"matches": ["*://*.example.com/*"]
}],
...
contentscript.js
function getPoints() {
var iframe = document.createElement('iframe');
iframe.src = 'http://www.example.com/';
// Remove iframe when the content has (not) loaded
iframe.onerror =
iframe.onload = function() {
setTimeout(function() {
iframe.parentNode.removeChild(iframe);
}, 5000);
};
// Put security restrictions on the iframe
iframe.sandbox = 'allow-scripts';
// Make frame invisible
iframe.style.height = '1px';
iframe.style.width = '1px';
iframe.style.position = 'fixed';
iframe.style.top = '-9px';
iframe.style.left = '-9px';
// Insert iframe in the document, and load its content
document.body.appendChild(iframe);
}
function sendPoints(attempts) {
var points = document.getElementsByClassName('notification-count hidden');
if (points.length > 1) { // <-- Example, based on your question
// Desired element found, send the message to the background page
chrome.runtime.sendMessage({
points: points[1].textContent
});
} else if (--attempts > 0) {
// Element not found, and some attempts left. Try again soon.
setTimeout(sendPoints, 250, attempts);
}
}
sendPoints(40);
这种方法有一个巨大的延迟:首先需要加载页面,然后加载和解析所有脚本和资源。如果可能,尝试用其他方法提取“动态”信息。尝试对您正在抓取的页面进行反向工程,并尝试通过其他方式获得所需的值,例如通过使用XMLHttpRequest
从生成元素的脚本中获取数据。