Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何仅在客户端重定向发生后结束PhantomJS脚本_Phantomjs - Fatal编程技术网

如何仅在客户端重定向发生后结束PhantomJS脚本

如何仅在客户端重定向发生后结束PhantomJS脚本,phantomjs,Phantomjs,我正在将PhantomJS headless浏览器集成到我的一个项目中(目前使用的是1.6版)。在很大程度上,它在完成我需要完成的任务方面做得很好。然而,WebPage.open()调用工作方式的异步性质,以及在某个时候需要调用phantom.exit(),使得在无法预测客户端重定向的方向时处理客户端重定向变得很棘手 我想要的是一种只在任何元刷新(导致另一个页面)和绑定到onload事件的JavaScript重定向执行后调用phantom.exit()的方法。我可以理解为什么这是一个问题,因为理

我正在将PhantomJS headless浏览器集成到我的一个项目中(目前使用的是1.6版)。在很大程度上,它在完成我需要完成的任务方面做得很好。然而,WebPage.open()调用工作方式的异步性质,以及在某个时候需要调用phantom.exit(),使得在无法预测客户端重定向的方向时处理客户端重定向变得很棘手

我想要的是一种只在任何元刷新(导致另一个页面)和绑定到onload事件的JavaScript重定向执行后调用phantom.exit()的方法。我可以理解为什么这是一个问题,因为理论上,客户端重定向可以在页面加载后的任何秒数内发生,我不能简单地要求只有在不再发生重定向时才能退出。现在,我能想到的最佳解决方案是a)手动检测页面上是否存在元刷新元素,并自己处理这些元素,b)使用setInterval()在调用phantom.exit()之前留出一些合理的时间(例如,1-1.5秒)。基本上是这样的:

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之前,包括onload事件。我还对可能需要等待的时间间隔进行了一些测试,虽然1000毫秒的时间足以让JavaScript重定向(通过body onload事件)在一个小测试页面中执行,但100毫秒的时间不够长。

我想到了使用模拟计时器来实现这一目的。假设我们在页面中包含。这样,您可以快进时间以避免js空闲时间。请参见GitHub页面上的示例


这只是一种使事情更快发生的方法,但正如您所料,无法确保将来是否会触发重定向事件。

我在加载优化使用的页面时遇到了相同的问题,而变化是一个location.href重定向

我现在在“renderPage”函数中使用onNavigationRequest回调。这些优化重定向不再阻塞,我不需要任意超时

var webpage=require('webpage');
var page=null;
var renderPage=函数(myurl){
page=webpage.create();
page.onNavigationRequested=函数(url、类型、willNavigate、主){
if(main&&url!=myurl&&url.replace(/\/$/,“”)!=myurl&&(type==“其他”| type==“未定义”)){
//main=主框架中的导航;type=不通过单击/提交等
日志(“\t以下“+myurl+”重定向到“+url”)
myurl=url;
page.close();
renderPage(url);//使用新url重新运行此函数
}
};//在Nav req上
打开页面(myurl、函数(状态){
如果(状态==“成功”){
页面渲染(“screenshot.jpg”);
}否则{
page.close();
}
});//打开页面
}//呈现页面
渲染页(“http://some.domain.com");

请参阅文档:

我已经检查了phantomjs重定向处理的各种示例:运气不好

目前还没有通用的解决方案。如果你修补一些脚本 ,在其他情况下,它将失败,例如除了使用location.href,使用javascript重定向。我还没有测试过尸体。在到处修补了几笔钱之后,我放弃了


我只是用“重”的Selenium触发的firefox来解决我的问题。如果您需要加载许多页面,而不是重新启动firefox,只需使用
webdriver.delete_all_cookies()
清除一些陷阱即可。与phantomjs相比,它给了我可靠的结果(我需要进行屏幕截图、下载html、获取最终url等等)。我在项目中使用了相同的方法,即在调用之间添加了一点停顿。恐怕这是唯一的选择(目前)。这将适用于标题重定向、js重定向和用户操作,对吗?@cmcdragokai:根据我的使用情况,这适用于URL中的任何更改-因此我们收到一个302->浏览器向其发出新请求->导航更改相同的事情,如果您通过JavaScript执行location.href;用户操作(即,模拟鼠标点击和表单提交等)的处理方式不同:更改了“类型”值(类型:可能的值包括:“未定义”、“链接单击”、“表单提交”、“后退或前进”、“重新加载”、“表单重新提交”、“其他”)