文档章节

Nodejs使用eventproxy控制并发数

webphp
 webphp
发布于 2017/07/26 11:28
字数 1058
阅读 27
收藏 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
码字总数 92070
作品 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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

day63-20180821-流利阅读笔记-待学习

性别歧视在日本:“我是女生,所以社会不让我学医” 毛西 2018-08-21 1.今日导读 大家在看病的时候,有留意过女医生的比例吗?在性别歧视现象十分严重的日本,男医生和女医生的比例达到了惊人...

aibinxiao
46分钟前
2
0
Ubuntu18.04 显卡GF-940MX安装NVIDIA-390.77

解决办法: 下面就给大家一个正确的姿势在Ubuntu上安装Nvidia驱动: (a)首先去N卡官网下载自己显卡对应的驱动:www.geforce.cn/drivers (b)下载后好放在英文路径的目录下,怎么简单怎么来...

AI_SKI
今天
4
0
深夜胡思乱想

魔兽世界 最近魔兽世界出了新版本, 周末两天升到了满级,比之前的版本体验好很多,做任务不用抢怪了,不用组队打怪也是共享拾取的。技能简化了很多,哪个亮按哪个。 运维 服务器 产品 之间的...

Firxiao
今天
1
0
MySQL 8 在 Windows 下安装及使用

MySQL 8 带来了全新的体验,比如支持 NoSQL、JSON 等,拥有比 MySQL 5.7 两倍以上的性能提升。本文讲解如何在 Windows 下安装 MySQL 8,以及基本的 MySQL 用法。 下载 下载地址 https://dev....

waylau
今天
1
0
微信第三方平台 access_token is invalid or not latest

微信第三方开发平台code换session_key说的特别容易,但是我一使用就带来无穷无尽的烦恼,搞了一整天也无济于事. 现在记录一下解决问题的过程,方便后来人参考. 我遇到的这个问题搜索了整个网络也...

自由的开源
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部