我正在将 PhantomJS 无头浏览器集成到我的一个项目中(目前使用 1.6 版)。在大多数情况下,它在完成我需要完成的工作方面做得很好。但是,WebPage.open() 调用工作方式的异步性质,以及在某些时候调用 phantom.exit() 的需要,使得当您无法预测客户端重定向的去向时处理客户端重定向变得很棘手去。
我所追求的是一种仅在任何元刷新(导致不同页面)和与 onload 事件等相关的 JavaScript 重定向执行后调用 phantom.exit() 的方法。我知道为什么这是一个问题,因为理论上客户端重定向可以在页面加载后的任意秒数发生,我不能简单地要求只有在不再发生重定向时才能退出. 现在,我能想到的最好的解决方案是 a) 手动检测页面上是否存在元刷新元素并自己处理这些元素,b) 使用 setInterval() 来留出一些理智的时间(比如 1- 1.5 秒)在调用 phantom.exit() 之前经过。它基本上看起来像这样:
var page = require('webpage').create();
var visitComplete = false;
var url = "http://some.url";
var pageOpenedTime;
setInterval(function() {
if (visitcomplete && typeof pageOpenedTime != 'undefined' &&
new Date() - pageOpenedTime >= 1500)
{
phantom.exit();
}
), 1000);
page.open(url, function() {
pageOpenedTime = new Date();
if (!hasMetaRefresh(page)) {
visitComplete = true;
}
});
function hasMetaRefresh(page) {
// Query the DOM here to detect meta refresh elements
}
有更好的想法吗?
编辑:我应该提到我的第一个想法是,当执行与初始页面加载相关的 JavaScript 时,可能会触发一个 PhantomJS 事件,但 onLoadFinished 回调似乎先于任何页内 JavaScript 的执行,包括加载事件。我还测试了我可能需要等待多少时间间隔,虽然 1000 毫秒足以让 JavaScript 重定向(通过 body onload 事件)在一个小测试页面中执行,但 100 毫秒还不够长。