NodeJS制作爬虫全过程(续)


Posted in NodeJs onDecember 22, 2014

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

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

{<1>}

NodeJS制作爬虫全过程(续)

在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>}

NodeJS制作爬虫全过程(续)

找到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>}

NodeJS制作爬虫全过程(续)

但是问题来了,我们在.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>}

NodeJS制作爬虫全过程(续)

我的做法就是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>}

NodeJS制作爬虫全过程(续)

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

{<7>}

NodeJS制作爬虫全过程(续)

NodeJs 相关文章推荐
NodeJS的url截取模块url-extract的使用实例
Nov 18 NodeJs
nodejs中使用monk访问mongodb
Jul 06 NodeJs
基于NodeJS的前后端分离的思考与实践(一)全栈式开发
Sep 26 NodeJs
详解nodejs 文本操作模块-fs模块(四)
Dec 22 NodeJs
详解nodejs中的process进程
Mar 19 NodeJs
3分钟快速搭建nodejs本地服务器方法运行测试html/js
Apr 01 NodeJs
让nodeJS支持ES6的词法----babel的安装和使用方法
Jul 31 NodeJs
Nodejs 和Session 原理及实战技巧小结
Aug 25 NodeJs
nodejs更改项目端口号的方法
May 13 NodeJs
Mac下通过brew安装指定版本的nodejs教程
May 17 NodeJs
nodejs中实现修改用户路由功能
May 24 NodeJs
Nodejs监控事件循环异常示例详解
Sep 22 NodeJs
NodeJS制作爬虫全过程
Dec 22 #NodeJs
nodejs中操作mysql数据库示例
Dec 20 #NodeJs
轻松创建nodejs服务器(10):处理上传图片
Dec 18 #NodeJs
轻松创建nodejs服务器(10):处理POST请求
Dec 18 #NodeJs
轻松创建nodejs服务器(7):阻塞操作的实现
Dec 18 #NodeJs
轻松创建nodejs服务器(8):非阻塞是如何实现的
Dec 18 #NodeJs
轻松创建nodejs服务器(9):实现非阻塞操作
Dec 18 #NodeJs
You might like
Zerg建筑一览
2020/03/14 星际争霸
php中的常用魔术方法总结
2013/08/02 PHP
php实现图片缩放功能类
2013/12/18 PHP
浅析Yii2缓存的使用
2016/05/10 PHP
硬盘浏览程序,保存成网页格式便可使用
2006/12/03 Javascript
js Array对象的扩展函数代码
2013/04/24 Javascript
form表单只提交数据而不进行页面跳转的解决方案
2013/09/18 Javascript
jQuery获取iframe的document对象的方法
2014/10/10 Javascript
浅谈JavaScript 中有关时间对象的方法
2016/08/15 Javascript
Jquery组件easyUi实现手风琴(折叠面板)示例
2016/08/23 Javascript
浅谈JavaScript异步编程
2017/01/20 Javascript
原生JS实现圆环拖拽效果
2017/04/07 Javascript
React diff算法的实现示例
2018/04/20 Javascript
jQuery easyui datagird编辑行删除行功能的实现代码
2018/09/20 jQuery
微信小程序使用canvas的画图操作示例
2019/01/18 Javascript
详解vue更改头像功能实现
2019/04/28 Javascript
记录vue项目中遇到的一点小问题
2019/05/14 Javascript
layui表单验证select下拉框实现验证的方法
2019/09/05 Javascript
[48:51]完美世界DOTA2联赛PWL S2 Magma vs InkIce 第一场 11.28
2020/12/02 DOTA
matplotlib 纵坐标轴显示数据值的实例
2018/05/25 Python
Random 在 Python 中的使用方法
2018/08/09 Python
Python logging模块用法示例
2018/08/28 Python
np.newaxis 实现为 numpy.ndarray(多维数组)增加一个轴
2019/11/30 Python
Python的PIL库中getpixel方法的使用
2020/04/09 Python
前端面试必备之CSS3的新特性
2017/09/05 HTML / CSS
用CSS3实现瀑布流布局的示例代码
2017/11/10 HTML / CSS
自主招生教师推荐信
2014/05/10 职场文书
主题班会演讲稿
2014/05/22 职场文书
人事行政专员岗位职责
2014/07/23 职场文书
创建绿色学校先进个人材料
2014/08/20 职场文书
大学生第一学年自我鉴定
2014/09/12 职场文书
法英专业大学生职业生涯规划范文:衡外情,量己力!
2014/09/23 职场文书
缓刑人员思想汇报
2014/10/11 职场文书
校园安全教育心得体会
2016/01/15 职场文书
用Python爬虫破解滑动验证码的案例解析
2021/05/06 Python
利用Python判断整数是否是回文数的3种方法总结
2021/07/07 Python