文档章节

Nodejs使用eventproxy控制并发数

webphp
 webphp
发布于 2017/07/26 11:28
字数 1058
阅读 25
收藏 0
点赞 0
评论 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
博文 91
码字总数 91650
作品 0
海淀
程序员
[分享] 用NodeJs做一个小爬虫,附源码!

前言 利用爬虫可以做很多事情,单身汉子们可以用爬虫来收集各种妹子情报,撩妹族们可以用爬虫收集妹子想要的小东西,赚大钱的人可以用来分析微博言论与股票涨跌的关系诸如此类的,简直要上天...

没错就是酱紫 ⋅ 2016/08/03 ⋅ 0

《Node.js 包教不包会》

《Node.js 包教不包会》 -- by alsotang 在 CNode 混了那么久,解答了不少 Node.js 初学者们的问题。回头想想,那些问题所需要的思路都不难,但大部分人由于练手机会少,所以在遇到问题的时候...

红薯 ⋅ 2014/10/21 ⋅ 11

wolfx/node-lessons

《Node.js 包教不包会》 -- by alsotang 为何写作此课程 在 CNode(https://cnodejs.org/) 混了那么久,解答了不少 Node.js 初学者们的问题。回头想想,那些问题所需要的思路都不难,但大部分...

wolfx ⋅ 2016/11/11 ⋅ 0

【深入浅出Node.js系列四】Node.js的事件机制

深入浅出Node.js系列 【深入浅出Node.js系列一】什么是Node.js 【深入浅出Node.js系列二】Node.js&NPM的安装与配置 【深入浅出Node.js系列三】深入Node.js的模块机制 【深入浅出Node.js系列四...

陶邦仁 ⋅ 2016/01/08 ⋅ 0

一个前端工程师眼里的NodeJS

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

大德 ⋅ 2012/09/25 ⋅ 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

NodeJS优缺点及适用场景讨论

NodeJS宣称其目标是“旨在提供一种简单的构建可伸缩网络程序的方法”,那么它的出现是为了解决什么问题呢,它有什么优缺点以及它适用于什么场景呢? 我关于node.js长处的理解: 1、node.js通...

金馆长1 ⋅ 2015/09/17 ⋅ 0

node.js适用的场景

概述:NodeJS宣称其目标是“旨在提供一种简单的构建可伸缩网络程序的方法”,那么它的出现是为了解决什么问题呢,它有什么优缺点以及它适用于什么场景呢? 本文就个人使用经验对这些问题进行...

疯狂的兔子 ⋅ 2014/07/31 ⋅ 0

Node.js 线程你理解的可能是错的

Node.js是单线程的,那么Node.js启动后线程数是1? 答案:Node.js启动后线程数并不是1,以下面代码为例 通过Mac实用工具 > 活动监视器可以查看进程的线程数其实是6 Node.js启动的线程数不为1...

Randal ⋅ 06/11 ⋅ 0

NodeJS系列~第一个小例子,实现了request.querystring功能

百度百科上: Node.js是一套用来编写高性能网络服务器的JavaScript工具包,一系列的变化由此开始,在Node中,Http是首要的。Node为创建http服务器作了优化,所以在网上看到的大部分示例和库都...

mcy247 ⋅ 2017/12/07 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 1

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

创建新用户和授予MySQL中的权限教程

导读 MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据。 它有多种选项来授予特定用户在表和数据库中的细微的权限 - 本教程将简要介绍一些选项。 如何创建新用户 在MySQL...

问题终结者 ⋅ 昨天 ⋅ 0

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 昨天 ⋅ 0

CentOS开机启动subversion

建立自启动脚本: vim /etc/init.d/subversion 输入如下内容: #!/bin/bash## subversion startup script for the server## chkconfig: 2345 90 10# description: start the subve......

随风而飘 ⋅ 昨天 ⋅ 0

Nginx + uwsgi @ubuntu

uwsgi 安装 sudo apt-get install python3-pip # 注意 ubuntu python3默认没有安装pippython3 -m pip install uwsgi 代码(test.py) def application(env, start_response): start_res......

袁祾 ⋅ 昨天 ⋅ 0

版本控制工具

CSV , SVN , GIT ,VSS

颖伙虫 ⋅ 昨天 ⋅ 0

【2018.06.19学习笔记】【linux高级知识 13.1-13.3】

13.1 设置更改root密码 13.2 连接mysql 13.3 mysql常用命令

lgsxp ⋅ 昨天 ⋅ 0

LVM

LVM: 硬盘划分分区成物理卷->物理卷组成卷组->卷组划分逻辑分区。 1.磁盘分区: fdisk /dev/sdb 划分几个主分区 输入t更改每个分区类型为8e(LVM) 使用partprobe生成分区的文件:如/dev/sd...

ZHENG-JY ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部