无法将数组项传递给 PhantomJS 中的函数
Can't pass array items to function in 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 循环只会迭代一次,然后其他两个函数会自己循环,所以这是有道理的,但仍然有问题 运行.
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
可能是 URL 在这种情况下,您可能想定义另一种方式来设计文件名。
- 虽然
for(var i in arrdata){ next_page(arrdata[i]); }
在这里起作用,但请注意,这不适用于所有数组和类似数组的对象。如果可用,请使用像 for(var i = 0; i < length; i++)
或 array.forEach(function(item, index){...})
这样的 dumb for 循环。
page.evaluate()
被沙盒化并提供对 DOM 的访问,但所有非 JSON 可序列化的内容都无法从中传递出去。在将其从 evaluate()
. 传递出去之前,您必须将其转换为可序列化格式
我正在尝试一次将源代码拉到多个网页。链接通过源文本文件输入到数组中。我能够遍历数组并打印出链接并确认它们在那里,但是当试图通过函数传递它们时,它们在第一次迭代后变得未定义。
我的最终目标是让它把每一页的源代码保存到它自己的文档中。它正确地完成了第一页,但后续尝试未定义。我已经搜索了几个小时,但如果有人能指出正确的方向,我将不胜感激。
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 循环只会迭代一次,然后其他两个函数会自己循环,所以这是有道理的,但仍然有问题 运行.
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
可能是 URL 在这种情况下,您可能想定义另一种方式来设计文件名。- 虽然
for(var i in arrdata){ next_page(arrdata[i]); }
在这里起作用,但请注意,这不适用于所有数组和类似数组的对象。如果可用,请使用像for(var i = 0; i < length; i++)
或array.forEach(function(item, index){...})
这样的 dumb for 循环。 page.evaluate()
被沙盒化并提供对 DOM 的访问,但所有非 JSON 可序列化的内容都无法从中传递出去。在将其从evaluate()
. 传递出去之前,您必须将其转换为可序列化格式