node.js中的同步获取url?
有没有办法从指定的url同步获取页面源? 问题是我有一个很长的URL列表(比如1000个)要获取和解析,在回调中循环执行这项操作非常痛苦,因为它同时启动所有的fetchUrl函数,并根据回调中的代码解析它 我更希望能够:node.js中的同步获取url?,node.js,Node.js,有没有办法从指定的url同步获取页面源? 问题是我有一个很长的URL列表(比如1000个)要获取和解析,在回调中循环执行这项操作非常痛苦,因为它同时启动所有的fetchUrl函数,并根据回调中的代码解析它 我更希望能够: 获取url1 解析url1源 将解析结果保存到硬盘 获取url2 解析url2源 将解析结果保存到硬盘 。。对所有列表重复此操作 目前,我使用fetch包获取url源,并使用cheerio进行解析。作为web服务器,节点的体系结构和响应能力取决于它没有执行同步(例如阻塞)网络操
目前,我使用fetch包获取url源,并使用cheerio进行解析。作为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();
}
函数处理URL(arrayOfURLs){
var i=0;
函数next(){
if(i
为了获得更好的端到端性能,您实际上可能希望让N个异步操作同时进行,而不是真正地序列化它们
您还可以为node.js使用Promissions或几个异步管理库中的任意一个。作为web服务器,node的体系结构和响应取决于它不执行同步(例如阻塞)网络操作。如果您打算在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();
}
函数处理URL(arrayOfURLs){
var i=0;
函数next(){
if(i
为了获得更好的端到端性能,您实际上可能希望让N个异步操作同时进行,而不是真正地序列化它们
您还可以为node.js使用Promissions或几个异步管理库中的任意一个。使用
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..');
};
使用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..');
};
同步I/O和节点不混合。如果您真的想进行此同步,那么使用Node将不会获得任何好处—这甚至不可能实现。你可以用Ruby来代替
其他答案是在生产服务器上执行此操作的正确方法。您应该将请求提交到某种可以限制并发性的队列中,这样您就不会试图一次完成1000个连接。我喜欢这个
如果这不是用于生产,并且可以使用不稳定的节点版本,则可以获得同步样式语法,该语法使用生成器通过“<代码>收益率<代码> >关键字:
在函数的中间停止执行。
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());
}
})();
或使用:
同步I/O和节点不混合。如果您真的想进行此同步,那么使用Node将不会获得任何好处—这甚至不可能实现。你可以用Ruby来代替
其他答案是在生产服务器上执行此操作的正确方法。您应该将请求提交到某种可以限制并发性的队列中,这样您就不会试图一次完成1000个连接。我喜欢这个
如果这不是用于生产,并且可以使用不稳定的节点版本,则可以获得同步样式语法,该语法使用生成器通过“<代码>收益率<代码> >关键字:
在函数的中间停止执行。
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());
}
})();
或使用:
这次响应性不是问题。我知道我正在打破设计模式,但对于这项任务,我宁愿同步完成,至少在我的脑海中是这样,但似乎有一些适合我的案例的模式我没有意识到。@Quest-那么你可能使用了错误的工具。这次响应性不是问题。我知道我正在打破设计模式,但对于这项任务,我宁愿同步进行,至少在我看来是这样,但似乎有一些适合我的案例的模式我并不知道。@Quest-那么你可能使用了错误的工具。这不会并行发出100个请求,它受到http客户端的限制-只是想澄清一下。这不会并行发出100个请求,它受到http客户端的限制-只是想澄清一下。