我有一个奇怪的问题。如果我调用此代码在主执行行中发出http请求:
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Print the google web page.
}
})
正如预期的那样打印Google页面HTML。
但是,我正在进行批量下载脚本/爬虫,所以我正在解析一个非常大的JSON文件,然后对我从该文件生成的每个URL执行请求。
要进行解析,我使用的是JSONStream解析器。这是代码:
parser.on('data', function (obj) {
console.log("Found uri");
console.log(obj);
});
正在正确运行代码,因为URI正在我的控制台中打印。
但是,如果我在解析块中发出请求,则永远不会执行请求回调....这是代码:
parser.on('data', function (obj) {
console.log("Found uri");
console.log(obj);
var identifierArray = obj['dc.identifier'];
if(identifierArray != null && identifierArray instanceof Array)
{
for(var i = 0; i < identifierArray.length; i++)
{
var dryadIdentifier = identifierArray[i];
if(dryadIdentifier.indexOf("dryad") != -1)
{
var fullUrl = "http://datadryad.org/resource/"+dryadIdentifier+"/mets.xml"
//var fileDestination = __dirname +"/"+downloadSubDir+"/"+dryadIdentifier.replace("/","_")+".xml"
var fileDestination = __dirname +"/"+downloadSubDir+"/"+fileCounter+".xml";
fileCounter++;
console.log("Sending request to "+ fullUrl + " ...");
//REQUEST SENT HERE; SAME CODE AS ABOVE.
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Print the google web page.
}
})
sleep.usleep(500000); //dont hammer the server
}
}
}
});
日志显示
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.s737f/mets.xml ...
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.s737f/1/mets.xml ...
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.1fd83/mets.xml ...
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.1fd83/1/mets.xml ...
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.4vk6d/mets.xml ...
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.c3k8m/mets.xml ...
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.5410v/mets.xml ...
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.492r0/mets.xml ...
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.m6g1b/mets.xml ...
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.m6g1b/1/mets.xml ...
Sending request to http://datadryad.org/resource/doi:10.5061/dryad.4dm30/mets.xml ...
但是没有打印html(它应该多次打印google主页,因为我还没有使用我从json解析的url,以排除目标服务器的问题。
很抱歉这封长信,但我对这种行为感到茫然(仍在学习nodejs ......: - O)
答案 0 :(得分:1)
似乎该问题与“sleep”调用有关,因此我使用semaphore库实现了一个基本连接队列。我现在指定最多10个同时连接,这是我的代码:
var makeRequestAndSaveToFile = function(url, absolutePath)
{
sem.take(function(){
console.log("Sending request to "+ url + " ... and saving to file "+absolutePath);
request(url, function(error,response, body) {
if (!error && response.statusCode == 200) {
fs.writeFile(absolutePath, body, function(err) {
sem.leave();
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
}
});
});
}
我为每个要下载的链接调用此函数。
请注意,这不会处理大量下载,因为没有管道,链接将以Slavo在评论中所说的无序方式下载。