文档章节

Nodejs使用eventproxy控制并发数

webphp
 webphp
发布于 2017/07/26 11:28
字数 1058
阅读 35
收藏 0

昨天在使用 superagent 与 cheerio 完成简单爬虫已经可以利用superagent简单的实现网页爬虫功能,可以根据给定的url地址获取文章列表标题、链接、发布时间等功能,今天使用eventproxy控制并发数的功能,需要取出每个主题的第一条评论,这就要求我们对每个主题的链接发起请求,并用 cheerio 去取出其中的第一条评论
这次要用到三个库superagent cheerio eventproxy  eventproxy的学习文档https://github.com/JacksonTian/eventproxy#%E9%87%8D%E5%A4%8D%E5%BC%82%E6%AD%A5%E5%8D%8F%E4%BD%9C

eventproxy的特点:

  1. 利用事件机制解耦复杂业务逻辑
  2. 移除被广为诟病的深度callback嵌套问题
  3. 将串行等待变成并行等待,提升多异步协作场景下的执行效率
  4. 友好的Error handling
  5. 无平台依赖,适合前后端,能用于浏览器和Node.js
  6. 兼容CMD,AMD以及CommonJS模块环境

要得到的效果是:

[ { title: '置顶\n\n\n\n CNode社区 for Ionic [2015-02-07更新][1.2.1已上架
][求issue]',
href: 'https://cnodejs.org/topic/545aee5a3e1f39344c5b3b3e',
comment1: '看起来还比较粗糙嘛' },
{ title: '回馈各位Noder,Iris来给大家送亚马逊礼品卡~!',
href: 'https://cnodejs.org/topic/554060bc208c44bf37c24d93',
comment1: '《深夜食堂》有书~' },
]

首先安装eventproxy库

npm install eventproxy

其次在app.js中写好路由,

var superagent = require('./routes/superagent');
app.get('/superagent/eventurl', superagent.eventurl);//superagent请求网页爬虫之先获取列表的url地址。在获取文章内部的第一个评论内容

/routes/superagent.js

第一步先获取列表中的所的url地址

var eventproxy = require('eventproxy');//处理nodejs并发的插件
var cheerio = require('cheerio');//类似于jquery库
var superagent = require('superagent');//为了做网页爬虫,引入superagent,http 方面的库,可以发起 get 或 post 请求 (npm install superagent)
var url = require('url');// url 模块是 Node.js 标准库里面的
exports.eventurl = function(req, res){
	var cnodeUrl = 'https://cnodejs.org/';
	superagent.get(cnodeUrl)
		.end(function(err, res) {
			if ( err ) {
				return console.error( err );
			};
			var topicUrls = [];
			var $ = cheerio.load(res.text);
			// 获取首页所有的链接
			$("#topic_list .topic_title").each(function(index, element){
				var $element = $(element);
				// $element.attr('href') 本来的样子是 /topic/542acd7d5d28233425538b04
      			// 我们用 url.resolve 来自动推断出完整 url,变成
			    // https://cnodejs.org/topic/542acd7d5d28233425538b04 的形式
      			// 具体请看 http://nodejs.org/api/url.html#url_url_resolve_from_to 的示例
				var href = url.resolve(cnodeUrl, $element.attr('href') );
				topicUrls.push(href);
			});
                        console.log(topicUrls);
               })

}

可以到到以下结果

[
'https://cnodejs.org/topic/55483b6bd6c067e36e41ab51'
'https://cnodejs.org/topic/5546ce60c5441de9545a3c10'
'https://cnodejs.org/topic/53c1f593400ca4581b79c5de'
'https://cnodejs.org/topic/5546f173c5441de9545a3c89'
'https://cnodejs.org/topic/554796f5d6c067e36e41aae2'
'https://cnodejs.org/topic/55422cbbbce63fb638715418'
'https://cnodejs.org/topic/5543ac050a21a480669ebe89'
'https://cnodejs.org/topic/5544bbe30a21a480669ebed0'
]

这时候我们已经得到所有 url 的地址了,接下来,我们把这些地址都抓取一遍,就完成了,在这里说一下eventproxy,如果我们不用eventproxy库的话,传统的写法是定义一个变量,
var count =0,然后每次抓取成功以后count++,由于我们不知道在抓取的时候那个url是先完成的,只能用count == N的时候,然后在执行下一个函数。而eventproxy就起到了计数数的作用,eventproxy可以帮我们管理那个请求是否已经成功,完成之后会自动调用处理函数。下面用eventproxy来处理
全部代码为:

exports.eventurl = function(req, res){
	var cnodeUrl = 'https://cnodejs.org/';
	superagent.get(cnodeUrl)
		.end(function(err, res) {
			if ( err ) {
				return console.error( err );
			};
			var topicUrls = [];
			var $ = cheerio.load(res.text);
			// 获取首页所有的链接
			$("#topic_list .topic_title").each(function(index, element){
				var $element = $(element);
				// $element.attr('href') 本来的样子是 /topic/542acd7d5d28233425538b04
      			// 我们用 url.resolve 来自动推断出完整 url,变成
			    // https://cnodejs.org/topic/542acd7d5d28233425538b04 的形式
      			// 具体请看 http://nodejs.org/api/url.html#url_url_resolve_from_to 的示例
				var href = url.resolve(cnodeUrl, $element.attr('href') );
				topicUrls.push(href);
			});

			// 得到 topicUrls 之后
			// 得到一个 eventproxy 的实例
			var ep = new eventproxy();
			// 命令 ep 重复监听 topicUrls.length 次(在这里也就是 40 次) `topic_html` 事件再行动
			ep.after('topic_html', topicUrls.length, function(topics){
				// topics 是个数组,包含了 40 次 ep.emit('topic_html', pair) 中的那 40 个 pair
				// 开始行动
				topics = topics.map(function(topicPair){
					 // 接下来都是 jquery 的用法了
					var topicUrl = topicPair[0];
					var topicHtml = topicPair[1];
					var $ = cheerio.load( topicHtml );
					return ({
						title: $(".topic_full_title").text().trim(),
						href:topicUrl,
						comment1:$('.reply_content').eq(0).text().trim(),
					});
				});
				console.log( 'final:' );
				console.log( topics );
				// res.send( topic );
			});

			topicUrls.forEach(function(topicUrl){
				superagent.get(topicUrl)
					.end(function(err, res){
						console.log( 'fetch' + topicUrl + 'successful' );
						ep.emit('topic_html', [topicUrl, res.text]);
					})
			})
		})

}

eventproxy内部的一些函数使用正在学习,比如.emit... 大家也可以查看中文文档,https://github.com/JacksonTian/eventproxy#%E9%87%8D%E5%A4%8D%E5%BC%82%E6%AD%A5%E5%8D%8F%E4%BD%9C

 

© 著作权归作者所有

共有 人打赏支持
webphp
粉丝 1
博文 92
码字总数 92338
作品 0
海淀
程序员
深入浅出Node.js(四):Node.js的事件机制

Node.js的事件机制 Node.js在其Github代码仓库(https://github.com/joyent/node)上有着一句短短的介绍:Evented I/O for V8 JavaScript。这句近似广告语的句子却道尽了Node.js自身的特色所...

leeldy
2012/10/25
0
0
Node.js express 之mongoose 从异步回调函数返回值,类似于同步

Node.js是很好,异步回调模式返回值让我头疼不已啊,今日还是写下今天学习的成果,起由是因为在使用mongoose查询的时候,多个查询相互依赖会层层嵌套,看起来N不爽,我们可以使用并行查询完毕...

造化玉碟
2013/12/23
0
4
quick lua下自定义事件处理

Quick-Cocos2d-x中的事件机制在官方的文档中已经讲解得很清楚了,查看这里。 这些方法能处理绝大多数的事件,但如果要实现自定义的事件(例如我们自己实现一个类,对该类添加自定义的事件处理...

80后小子
2015/01/29
0
0
一个前端工程师眼里的NodeJS

JavaScript单线程的误解   在我接触JavaScript(无论浏览器还是NodeJS)的时间里,总是遇到有朋友有多线程的需求。而在NodeJS方面,有朋友甚至直接说到,NodeJS是单线程的,无法很好的利用...

大德
2012/09/25
0
0
初识JavaScript Promises

JavaScript有很多槽点,嵌套回调怕是千夫所指。 很久之前,我一直使用async来处理JavaScript异步编程中的嵌套回调问题。当然我也大概的了解过一些其它旨在解决这些问题的类库,诸如EventProx...

梵高
2014/06/29
0
15

没有更多内容

加载失败,请刷新页面

加载更多

linux 系统的运行级别

运行级别 运行级别 | 含义 0 关机 1 单用户模式,可以想象为windows 的安全模式,主要用于修复系统 2 不完全的命令模式,不含NFS服务 3 完全的命令行模式,就是标准的字符界面 4 系统保留 5 ...

Linux学习笔记
今天
2
0
学习设计模式——命令模式

任何模式的出现,都是为了解决一些特定的场景的耦合问题,以达到对修改封闭,对扩展开放的效果。命令模式也不例外: 命令模式是为了解决命令的请求者和命令的实现者之间的耦合关系。 解决了这...

江左煤郎
今天
3
0
字典树收集(非线程安全,后续做线程安全改进)

将500W个单词放进一个数据结构进行存储,然后进行快速比对,判断一个单词是不是这个500W单词之中的;来了一个单词前缀,给出500w个单词中有多少个单词是该前缀. 1、这个需求首先需要设计好数据结...

算法之名
昨天
15
0
GRASP设计模式

此文参考了这篇博客,建议读者阅读原文。 面向对象(Object-Oriented,OO)是当下软件开发的主流方法。在OO分析与设计中,我们首先从问题领域中抽象出领域模型,在领域模型中以适当的粒度归纳...

克虏伯
昨天
1
0
Coding and Paper Letter(四十)

资源整理。 1 Coding: 1.Tomislav Hengl撰写的非官方作者指南:Michael Gould•Wouter Gerritsma。 UnofficialGuide4Authors 2.R语言包rwrfhydro,社区贡献的工具箱,用于管理,分析和可视化...

胖胖雕
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部