[英]Node.js Recursion and Memory Limit
我正在嘗試抓取網站的數據,並且正在使用node.js進行此操作,因為使用javascript處理遍歷網頁的DOM似乎是一個好主意。
我遇到的問題是,由於明顯的原因,我不想太快地訪問Web服務器,因此我使用遞歸設置了時間延遲。 但是,在大約10,000條記錄之后,我達到了node.js的內存限制。 目前共有17,000條記錄。
var i = 0; // set your counter to 1
function myLoop (n) { // create a loop function
setTimeout(function () { // call a 1s setTimeout when the loop is called
request(url, function(error, response, html){
if(!error){
}
}) ;
i++; // increment the counter
if (i < ids.length) { // if the counter < ids.length, call the loop function
myLoop(); // .. again which will trigger another
} // .. setTimeout()
}, 2000)
}
myLoop(); // start the loop
上面是代碼中使用的遞歸循環。 我之所以使用遞歸,是因為請求是異步的,並且超時不會停止for循環。
我暫時使用的解決方案是運行兩次,然后將輸出復制並粘貼在一起。 必須有更好的方法來做到這一點。
這是代碼的完整版本(匿名)
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var json2csv = require('json2csv');
console.log('Starting');
ids = []
count = -1;
fs.readFile('data.csv', 'utf-8', function (err,data) {
if (err) {
return console.log(err);
}
console.log('### CSV data incoming ###');
console.log();
console.log(data);
console.log('### End of CSV data ###');
ids = data.split('\n');
});
var jsonFinal = new Array();
var i = 0; // set your counter to 1
function myLoop (n) { // create a loop function
setTimeout(function () { // call a 1s setTimeout when the loop is called
console.log('for loop ' + i);
url = 'http://www.example.org.uk/location/' + ids[i];
request(url, function(error, response, html){
if(!error){
var $ = cheerio.load(html);
var example1, example2, example3, example4, example5;
var json = {uid : "", name : "", example1 : "", example2 : "", example3 : "", example4 : "", example5 : ""};
//Traverse DOM here
jsonFinal.push(json);
count += 1;
console.log('Pushed JSON array ' + count)
if (count+1 == ids.length){
// To write to the system we will use the built in 'fs' library.
// In this example we will pass 3 parameters to the writeFile function
// Parameter 1 : output.json - this is what the created filename will be called
// Parameter 2 : JSON.stringify(json, null, 4) - the data to write, here we do an extra step by calling JSON.stringify to make our JSON easier to read
// Parameter 3 : callback function - a callback function to let us know the status of our function
//fields for the csv
var fields = ['uid', 'name', 'example1', 'example2', 'example3', 'example4', 'example5'];
fs.writeFile('output.json', JSON.stringify(jsonFinal, null, 4), function(err){
console.log('File successfully written! - Check your project directory for the output.json file');
})
json2csv({ data: jsonFinal, fields: fields }, function(err, csv) {
if (err) console.log(err);
fs.writeFile('output.csv', csv, function(err) {
if (err) throw err;
console.log('File successfully written! - Check your project directory for the output.csv file');
});
});
}
}
}) ;
i++; // increment the counter
if (i < ids.length) { // if the counter < ids.length, call the loop function
myLoop(); // .. again which will trigger another
} // .. setTimeout()
}, 2000)
}
myLoop(); // start the loop
只需將遞歸調用移至請求的回調,就不會損害堆棧
i++; // increment the counter
request(url, function(error, response, html){
if (i < ids.length) { // if the counter < ids.length, call the loop function
myLoop(); // .. again which will trigger another
}
// ...
if(!error){
// ...
}
}) ;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.