我的目标是使用以下方法执行PhantomJS:
// adding $op and $er for debugging purposes
exec('phantomjs script.js', $op, $er);
print_r($op);
echo $er;
然后在script.js
内,我计划使用多个page.open()
来捕获不同网页的屏幕截图,例如:
var url = 'some dynamic url goes here';
page = require('webpage').create();
page.open(url, function (status) {
console.log('opening page 1');
page.render('./slide1.png');
});
page = require('webpage').create();
page.open(url, function (status) {
console.log('opening page 2');
page.render('./slide2.png');
});
page = require('webpage').create();
page.open(url, function (status) {
console.log('opening page 3');
page.render('./slide3.png');
phantom.exit(); //<-- Exiting phantomJS only after opening all 3 pages
});
在运行exec
时,我在页面上得到以下输出:
Array ( [0] => opening page 3 ) 0
因此我只获得第3页的屏幕截图。我不确定为什么PhantomJS会跳过第一个和第二个代码块(从丢失的console.log()
消息中可以看出,它们应该从第一个和第二个块输出)并且只执行第三个代码块。
答案 0 :(得分:43)
问题是在第一个page.open
完成之前调用了第二个function handle_page(file){
page.open(file,function(){
...
page.evaluate(function(){
...do stuff...
});
page.render(...);
setTimeout(next_page,100);
});
}
function next_page(){
var file=args.shift();
if(!file){phantom.exit(0);}
handle_page(file);
}
next_page();
,这可能会导致多个问题。您希望逻辑大致如下(假设文件名作为命令行参数给出):
page.open
是的,它是递归的。这样可以确保在转到下一个文件之前,传递给page = require('webpage').create();
的函数的处理完成时间为100毫秒。
顺便说一下,你不需要继续重复
{{1}}
答案 1 :(得分:8)
我已经尝试了接受的答案建议,但它不起作用(至少不适用于v2.1.1)。
准确地说,接受的答案在某些时候有效,但我仍然经历了零星失败的page.open()调用,大约90%的时间用于特定数据集。
我找到的最简单的答案是为每个网址实例化一个新的页面模块。
// first page
var urlA = "http://first/url"
var pageA = require('webpage').create()
pageA.open(urlA, function(status){
if (status){
setTimeout(openPageB, 100) // open second page call
} else{
phantom.exit(1)
}
})
// second page
var urlB = "http://second/url"
var pageB = require('webpage').create()
function openPageB(){
pageB.open(urlB, function(){
// ...
// ...
})
}
The following from the page module api documentation on the close method says:
close(){void}
关闭页面并释放与其关联的内存堆。调用后不要使用页面实例。
由于某些技术限制,网页对象可能不会完全被垃圾收集。当一遍又一遍地使用相同的对象时经常会遇到这种情况。调用此函数可能会停止增加堆分配。
基本上在我测试了close()方法后,我决定对不同的open()调用使用相同的网页实例太不可靠了,需要说明。
答案 2 :(得分:2)
您可以使用递归:
modelmapper