说明:本文在个人博客地址为edwardesire.com,欢迎前来品尝。


书接上回,我们需要修改程序以达到连续抓取40个页面的内容。也就是说我们需要输出每篇文章的标题、链接、第一条评论、评论用户和论坛积分。


如图所示,$('.reply_author').eq(0).text().trim();得到的值即为正确的第一条评论的用户。

{<11>}

在eventproxy获取评论及用户名内容后,我们需要通过用户名跳到用户界面继续抓取该用户积分

var $ = cheerio.load(topicHtml);
//此URL为下一步抓取目标URL
var userHref = 'https://cnodejs.org' + $('.reply_author').eq(0).attr('href');
userHref = url.resolve(tUrl, userHref);
var title = $('.topic_full_title').text().trim().replace(/\n/g,"");;
var href = topicUrl;
var comment1 = $('.reply_content').eq(0).text().trim();
var author1 = $('.reply_author').eq(0).text().trim(); //传递参数到下一次并发抓取
ep.emit('user_html', [userHref, title, href, comment1, author1]);

在eventproxy这一次中,我们要找到score是放在哪里(class="big")。

{<2>}

找到classname就好办了,我们先试着把结果输出一下

var outcome = superagent.get(userUrl)
.end(function (err, res) {
if (err) {
return console.error(err);
}
var $ = cheerio.load(res.text);
var score = $('.big').text().trim();
console.log(user[1]);
console.log(user[2]);
console.log(user[3]);
console.log(user[4]);
console.log($('.big').text().trim()); return ({
title: user[1],
href: user[2],
comment1: user[3],
author1: user[4],
score1: score
});
});
});

运行程序,这段代码得到的结果。

{<3>}

但是问题来了,我们在.end()的回调函数中能正确输出结果,但是不能正确的输出outcome。仔细一看,需要输出的outcome是一个Request对象。这是因为粗心犯的错的,.end()函数并不会传递返回值给Request对象,需要将结果返回到上一层(users)。

//find userDetails
ep.after('user_html', topicUrls.length, function(users){
users = users.map(function(user){
var userUrl = user[0];
var score;
superagent.get(userUrl)
.end(function (err, res) {
if (err) {
return console.error(err);
}
//console.log(res.text);
var $ = cheerio.load(res.text);
score = $('.big').text().trim();
});
return ({
title: user[1],
href: user[2],
comment1: user[3],
author1: user[4],
score1: score
});
});

把users好好地输出发现除了score1其他是正确值。仔细调试发现,程序是先进行了console.log(),然后再进行.map()。更准确地说,在.map()函数内,.get()的回调函数并没有执行完赋值score,return 返回值就进行了。这就是回调函数的异步,而外层的同步操作是不会等待回调函数做完操作的。

{<4>}

我的做法就是eventproxy再emit一层消息,伴随着消息把需要的数据一起传递给接收消息操作.after(),只有当消息全部接收完毕,再打印出传递的参数(结果)。

score = $('.big')text().trim();
//新添加
ep.emit('got_score', [user[1], user[2], user[3], user[4], score]);
.....
ep.after('got_score', 10, function(users){
console.log(users);
});

{<6>}

这个问题解决了,但score1的数值好像太大了点吧。再一看,原来class='big'有两个,用户的话题收藏也是属于这个class。我们得通过cheerio的.slice( start, [end] )来切取第一个元素,即将score 修改为 score = $('.big').slice(0).eq(0).text().trim();。正确结果如图。

{<7>}

(完)

NodeJS学习:爬虫小探补完计划的更多相关文章

  1. [TaskList] 省选前板子补完计划

    省选前本子补完计划 [ ] 带权并查集 [ ] 树上莫队 - UOJ58 [WC2013]糖果公园 loj2485「CEOI2017」Chase

  2. NodeJS学习:爬虫小探

    说明:本文在个人博客地址为edwardesire.com,欢迎前来品尝. 今天来学习alsotang的爬虫教程,跟着把CNode简单地爬一遍. 建立项目craelr-demo 我们首先建立一个Expr ...

  3. bzoj Usaco补完计划(优先级 Gold>Silver>资格赛)

    听说KPM初二暑假就补完了啊%%% 先刷Gold再刷Silver(因为目测没那么多时间刷Silver,方便以后TJ2333(雾 按AC数降序刷 ---------------------------- ...

  4. CodeVS1169 传纸条 [DP补完计划]

    题目传送门 题目描述 Description 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端, ...

  5. QBXT 2017GoKing problems 补完计划

    10.11 Updata : 烦死了...麻烦死了...不补了..就这些吧 20171001 上: 100 + 90 + 90 = 280 = rank 8 T1 /* T1 从最大的数开始倒着枚举 ...

  6. NLP 开源形近字算法补完计划(完结篇)

    前言 所有的故事都有开始,也终将结束. 本文将作为 NLP 汉字相似度的完结篇,为该系列画上一个句号. 起-NLP 中文形近字相似度计算思路 承-中文形近字相似度算法实现,为汉字 NLP 尽一点绵薄之 ...

  7. 爬虫小探-Python3 urllib.request获取页面数据

    使用Python3 urllib.request中的Requests()和urlopen()方法获取页面源码,并用re正则进行正则匹配查找需要的数据. #forex.py#coding:utf-8 ' ...

  8. 洛谷P2224 [HNOI2001] 产品加工 [DP补完计划,背包]

    题目传送门 产品加工 题目描述 某加工厂有A.B两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成.由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时 ...

  9. POJ1742 Coin [DP补完计划]

    题目传送门 Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 41707   Accepted: 14125 Des ...

随机推荐

  1. 利用qt打开一张图片并转成灰度矩阵

    首先是mat类,这个类的主要作用是构造一个容器,并将对应像素的灰度值放在容器内 #ifndef MAT_H #define MAT_H #include <vector> #include ...

  2. bootstrap 3.x笔记

    布局容器 Bootstrap 需要为页面内容和栅格系统包裹一个 .container 容器.我们提供了两个作此用处的类.注意,由于 padding等属性的原因,这两种 容器类不能互相嵌套. .cont ...

  3. Awesome-awesome-awesome

    Awesome-awesome-awesome A curated list of curated lists of awesome lists. awesome-awesomes @sindreso ...

  4. The secret code

    The secret code Input file: stdinOutput file: stTime limit: 1 sec Memory limit: 256 MbAfter returnin ...

  5. dialog组件

    /** * @description Mask 弹层 * @function * @name Mask * @param {Object} options 配置项 */ var passport = ...

  6. Java [Leetcode 70]Climbing Stairs

    题目描述: You are climbing a stair case. It takes n steps to reach to the top. Each time you can either ...

  7. 【C#学习笔记】打开对话框并返回打开文件所在路径

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  8. NavieBayes中的多项式与伯努力模型

    1文本分类过程 例如文档:Good good study Day day up可以用一个文本特征向量来表示,x=(Good, good, study, Day, day , up).在文本分类中,假设 ...

  9. Darwin Streaming Server 简介

    Darwin Streaming Server     概要 Darwin Streaming Server简称DSS.DSS是Apple公司提供的开源实时流媒体播放服务器程序.整个程序使用C++编写 ...

  10. Android手动画柱状图的例子

    效果图如上,网上看到的例子,谨以此文记录一下,以后用到的地方再来翻翻. 核心技术是用Canvas和Paint画长方形. 源码地址:http://download.csdn.net/detail/abc ...