无法传递数组项以在PhantomJS

时间:2015-07-15 03:04:59

标签: javascript arrays phantomjs

我正在尝试将源代码同时提取到多个网页。链接通过源文本文件提供给数组。我能够遍历数组并打印出链接并确认它们在那里,但是当试图通过函数传递它们时,它们在第一次迭代后变得不确定。

我的最终目标是将每个页面的来源保存到自己的文档中。它正确执行第一页,但后续尝试未定义。我已经搜索了几个小时,但如果有人能指出我正确的方向,我会很感激。

var fs = require('fs');
var pageContent = fs.read('input.txt');
var arrdata = pageContent.split(/[\n]/);
var system = require('system');
var page = require('webpage').create();
var args = system.args;
var imagelink;
var content = " ";

function handle_page(file, imagelink){
    page.open(file,function(){
        var js = page.evaluate(function (){
            return document;
        });
        fs.write(imagelink, page.content, 'w');
        setTimeout(next_page(),500);
    });
}
function next_page(imagelink){
    var file = imagelink;
    if(!file){phantom.exit(0);}
    handle_page(file, imagelink);
}

for(var i in arrdata){
    next_page(arrdata[i]);
}

我现在意识到,for循环只会迭代一次,然后其他两个函数会自行循环,所以这很有意义,但仍然有问题让它运行。

1 个答案:

答案 0 :(得分:0)

PhantomJS的page.open()是异步的(这就是回调的原因)。另一件事是page.open()是一个长期的操作。如果进行了两次此类调用,则第二次调用将覆盖第一次调用,因为您在相同的page对象上进行操作。

最好的方法是使用递归:

function handle_page(i){
    if (arrdata.length === i) {
        phantom.exit();
        return;
    }
    var imageLink = arrdata[i];
    page.open(imageLink, function(){
        fs.write("file_"+i+".html", page.content, 'w');
        handle_page(i+1);
    });
}
handle_page(0);

其他一些事情:

  • setTimeout(next_page(),500);立即调用next_page()而无需等待。您想要setTimeout(next_page, 500);,但它也不会起作用,因为没有参数next_page只是退出。
  • fs.write(imagelink, page.content, 'w') imagelink可能是一个网址,在这种情况下,您可能希望定义另一种设计文件名的方法。
  • 虽然for(var i in arrdata){ next_page(arrdata[i]); }在这里起作用,但请注意,这不适用于所有阵列和类似数组的对象。如果for(var i = 0; i < length; i++)array.forEach(function(item, index){...})可用,请使用dumb for for循环。
  • page.evaluate()是沙箱并提供对DOM的访问,但是不能通过JSON序列化传递的所有东西都不能传递给它。在将其传递出evaluate()之前,您必须将其置于可序列化的格式中。