chrome插件网页抓取(GoogleReader的执行环境和原始网页太复杂了(图) )
优采云 发布时间: 2022-04-12 17:22chrome插件网页抓取(GoogleReader的执行环境和原始网页太复杂了(图)
)
来自:%E5%9C%A8Chrome%E6%8F%92%E4%BB%B6%E4%B8%AD%E8%AE%BF%E9%97%AE%E5%8E%9F%E5%A7%8B %E7%BD%91%E9%A1%B5%E4%B8%AD%E7%9A%84%E5%8F%98%E9%87%8F
今天早上写Reader Sharer插件的时候遇到了一个问题。
谷歌阅读器网页有全局变量_COMMAND_TOKEN,我需要用到,但是Chrome插件的Content Scripts的执行环境和原网页不一样,所以无法直接使用window._COMMAND_TOKEN来获取。
如果是火狐,我可以使用 unsafeWindow._COMMAND_TOKEN 直接获取;Chrome插件很久以前就和原网页共享了执行环境,但是好日子已经一去不复返了。
幸运的是,我发现了“如何在 Chrome 中模仿 Greasemonkey/Firefox 的 unsafeWindow 功能?”这个问题。并得到3个解决方案。
考虑到谷歌阅读器的网页过于复杂,这里以谷歌主页为例。打开网页后,右键打开inspect元素,然后在控制台输入fp,会看到一个字符串,是原网页的全局变量。
现在我想得到它,我可以创建一个脚本元素并将其附加到头部。这个脚本元素的执行环境是原创网页,fp变量可以自由使用。
但是fp取出后,不能直接传回内容脚本。幸运的是,文档说 DOM 是共享的,所以在这个脚本中,可以将值设置为元素的属性或 innerText,然后在内容脚本中获取:
setTimeout(function() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.innerHTML = "document.body.setAttribute('data-fp', fp);";
document.head.appendChild(script);
document.head.removeChild(script);
console.log(document.body.getAttribute('data-fp'));
}, 1000);
这里延迟的原因是在加载原创网页时,创建fp变量需要一段时间。
另一种方式是使用location.href,用来跳转网页,但也可以用来执行JavaScript,执行环境也是原网页:
setTimeout(function() {
location.href = "javascript:document.body.setAttribute('data-fp', fp);";
setTimeout(function() {
console.log(document.body.getAttribute('data-fp'));
}, 0);
}, 1000);
SetTimeout 嵌套在这里,因为跳转是一个事件,不会中断当前脚本的执行(并且添加一个脚本元素会立即执行),所以下面的语句需要等待事件处理完毕。
但是,上面提到的方法必须先保存,然后取出。只有字符串等简单类型才能做到这一点,与函数无关。
其实还有一种更方便的方法,就是在DOM上绑定一个事件,事件处理函数返回window变量,然后在程序中触发这个事件,获取执行环境的window变量。好在这个执行环境还是原来网页的那个:
setTimeout(function() {
var div = document.createElement('div');
div.setAttribute('onclick', 'return window;');
var unsafeWindow = div.onclick();
console.log(unsafeWindow.fp);
}, 1000);