有沒有辦法從指定的URL同步頁面源? 問題是,我有一長串url(如其中的1000個)來獲取和解析,並在回調中循環執行它非常痛苦,因爲它同時啓動所有fetchUrl函數,並根據代碼在回調中。node.js中的syncronous提取url?
Preferebly我想能夠:
- 獲取爲url1
- 解析爲url1源
- 保存結果分析結果到硬盤
- 獲取URL2
- 解析URL2源
- 將結果解析結果保存到hdd
- ..重複所有列表。
目前我使用取包來獲取URL源解析cheerio。
有沒有辦法從指定的URL同步頁面源? 問題是,我有一長串url(如其中的1000個)來獲取和解析,並在回調中循環執行它非常痛苦,因爲它同時啓動所有fetchUrl函數,並根據代碼在回調中。node.js中的syncronous提取url?
Preferebly我想能夠:
目前我使用取包來獲取URL源解析cheerio。
使用async.queue
,request
,cheerio
這裏是使用async.queue
var Concurrency = 100; // how many urls to process at parallel
var mainQ =async.queue(function(url,callback){
request(url,function(err,res,body){
// do something with cheerio.
// save to disk..
console.log('%s - completed!',url);
callback(); // end task
});
},Concurrency);
mainQ.push(/* big array of 1000 urls */);
mainQ.drain=function(){
console.log('Finished processing..');
};
作爲Web服務器的節點的體系結構和響應性取決於它不進行同步(例如阻塞)網絡操作。如果你打算在node.js中開發,我建議你學習如何管理異步操作。
下面是運行序列化的異步操作的設計模式:
function processURLs(arrayOfURLs) {
var i = 0;
function next() {
if (i < arrayOfURLs.length) {
yourAsyncOperation(arrayOfURLS[i], function(result) {
// this callback code runs when async operation is done
// process result here
// increment progress counter
++i;
// do the next one
next();
});
}
}
next();
}
爲了更好的終端到終端的性能,你實際上可能要令N異步操作馬上走,而不是真正的序列化他們。
您還可以使用promise或node.js的多個異步管理庫中的任何一個。
同步I/O和節點不要混合您的問題,一個基本方法。如果你確實想要做這個同步,你沒有通過使用節點獲得任何東西 - 它甚至不可能。你可以用Ruby代替。
其他答案是在生產服務器上執行此操作的正確方法。您應該將請求提交給某種可以限制併發性的隊列,因此您不會一次嘗試建立1000個連接。我喜歡batch。
如果不生產,你可以使用節點的不穩定版本,你可以使用co它使用發電機通過yield
關鍵字停在一個函數中執行的同步式的語法:
var co = require('co'),
request = require('co-request'),
cheerio = require('cheerio');
var urls = [];
for (var i = 0; i < 10; i++)
urls.push('http://en.wikipedia.org/wiki/Special:Random');
co(function *() {
for (var i = 0; i < urls.length; i++) {
var res = yield request(urls[i]);
console.log(cheerio.load(res.body)('#firstHeading').text());
}
})();
運行帶:
node --harmony-generators random.js
或者使用regenerator:
regenerator -r random.js | node
不知道co,我會深深地看,謝謝。 – kaytrance
不錯!使用你的解決方案,就像一個魅力! – kaytrance
這不會並行發出100個請求,它受到http客戶端的限制 - 只是想澄清一下。 –