下面的脚本包含“links”数组中的一些网址。函数gatherLinks()
用于从“links”数组中的URL的sitemap.xml收集更多URL。一旦“links”数组有足够的URL(由变量“limit”决定),就会为“links”数组中的每个URL调用函数request()
,以向服务器发送请求并获取响应。报告每个响应所花费的时间。程序结束时会报告程序所用的总时间。
我写了一个PhantomJS程序(下面的源代码)来发送一些请求并计算所花费的时间(为了比较2.0.0和1.9.8的性能)。我使用“链接”数组中硬编码的网站的sitemap.xml文件获取链接。
当使用PhantomJS 2.0.0运行时,在大约65个请求之后,程序(请求函数的方法page.open()
)开始输出以下内容:
select: Invalid argument select: Invalid argument select: Invalid argument select: Invalid argument select: Invalid argument . . . .
使用PhantomJS 1.9.8运行时,它会在大约200个请求后崩溃并出现以下错误。
“PhantomJS已崩溃。请阅读https://github.com/ariya/phantomjs/wiki/Crash-Reporting的崩溃报告指南,并在https://github.com/ariya/phantomjs/issues/new上提交错误报告并附上崩溃转储文件:/ tmp / 2A011800-3367-4B4A-A945-3B532B4D9B0F的.dmp“
我试图发送崩溃报告,但他们的指南对我来说并不是很有用。
这不是我使用的网址,我尝试过使用其他网址但结果相同。
我的程序有问题吗?我正在使用OSX。
var system = require('system');
var fs = require('fs');
var links = [];
links = [
"http://somesite.com",
"http://someothersite.com",
.
.
.
];
var index = 0, fail = 0, limit = 300;
finalTime = Date.now();
var gatherLinks = function(link){
var page = require('webpage').create();
link = link + "/sitemap.xml";
console.log("Fetching links from " + link);
page.open(link, function(status){
if(status != "success"){
console.log("Sitemap Request FAILED, status: " + status);
fail++;
return;
}
var content = page.content;
parser = new DOMParser();
xmlDoc = parser.parseFromString(content, 'text/xml');
var loc = xmlDoc.getElementsByTagName('loc');
for(var i = 0; i < loc.length; i++){
if(links.length < limit){
links[links.length] = loc[i].textContent;
} else{
console.log(links.length + " Links prepared. Starting requests.\n");
index = 0;
request();
return;
}
}
if(index >= links.length){
index = 0;
console.log(links.length + " Links prepared\n\n");
request();
}
gatherLinks(links[index++]);
});
};
var request = function(){
t = Date.now();
var page = require('webpage').create();
page.open(links[index], function(status) {
console.log('Loading link #' + (index + 1) + ': ' + links[index]);
console.log("Time taken: " + (Date.now() - t) + " msecs");
if(status != "success"){
console.log("Request FAILED, status: " + status);
fail++;
}
if(index >= links.length-1){
console.log("\n\nAll links done, final time taken: " + (Date.now() - finalTime) + " msecs");
console.log("Requests sent: " + links.length + ", Failures: " + fail);
console.log("Success ratio: " + ((links.length - fail)/links.length)*100 + "%");
phantom.exit();
}
index++;
request();
});
}
gatherLinks(links[0]);
在玩完该程序后,我找不到任何特定模式来解决我在下面提到的问题。对于2.0.0,我只能成功发送300个请求而没有错误。我尝试了所有不同的URL组合,程序通常在请求50-80之间失败。我维护了一个失败的url日志,当我使用另一个PhantomJS程序发送一个请求时,所有这些都运行正常。对于1.9.8,它更稳定,我在下面提到的崩溃不是很频繁。但同样,我找不到崩溃的任何模式,它偶尔会崩溃。
答案 0 :(得分:0)
您的代码存在很多问题。主要原因可能是您为每个请求创建了一个新页面而之后从未关闭。我认为你的内存不足。
我没有看到为每个请求创建新页面的原因,因此您可以轻松地为所有请求重复使用单个页面。只需将行var page = require('webpage').create();
移至gatherLinks()
和request()
之外的全局范围即可。如果您不想这样做,那么您可以在完成之后致电page.close()
,但请记住PhantomJS的异步特性。
如果使用多个页面对象的原因是为了防止缓存重用以用于以后的请求,那么我必须告诉您这并不能解决该问题。单个PhantomJS进程中的page
个对象可以视为选项卡或窗口,它们共享cookie和缓存。如果要隔离每个请求,则需要在自己的流程中运行每个请求,例如通过使用Child Process Module。
您的代码还有另一个问题。您可能想在gatherLinks()
中编写以下内容:
if(index >= links.length){
index = 0;
console.log(links.length + " Links prepared\n\n");
request();
return; // ##### THIS #####
}
gatherLinks(links[index++]);