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根据ip数组在百度地图中进行定位
Mar 06 NodeJs
nodejs和C语言插入mysql数据库乱码问题的解决方法
Apr 14 NodeJs
nodejs 图解express+supervisor+ejs的用法(推荐)
Sep 08 NodeJs
nodejs实现的连接MySQL数据库功能示例
Jan 25 NodeJs
解决nodejs的npm命令无反应的问题
May 17 NodeJs
Nodejs Express 通过log4js写日志到Logstash(ELK)
Aug 30 NodeJs
nodeJS进程管理器pm2的使用
Jan 09 NodeJs
NodeJS读取分析Nginx错误日志的方法
May 14 NodeJs
nodejs实现UDP组播示例方法
Nov 04 NodeJs
在NodeJs中使用node-schedule增加定时器任务的方法
Jun 08 NodeJs
nodeJs项目在阿里云的简单部署
Nov 27 NodeJs
详解NodeJS模块化
Jun 15 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
mysql+php分页类(已测)
2008/03/31 PHP
解析file_get_contents模仿浏览器头(user_agent)获取数据
2013/06/27 PHP
PHP使用glob函数遍历目录或文件夹的方法
2014/12/16 PHP
php上传excel表格并获取数据
2017/04/27 PHP
thinkPHP框架通过Redis实现增删改查操作的方法详解
2019/05/13 PHP
jquery下操作HTML控件的实现代码
2010/01/12 Javascript
jquery photoFrame 图片边框美化显示插件
2010/06/28 Javascript
javascript学习笔记(四) Number 数字类型
2012/06/19 Javascript
Jquery实现侧边栏跟随滚动条固定(兼容IE6)
2014/04/02 Javascript
jQuery实现360°全景拖动展示
2015/03/18 Javascript
JS判断Android、iOS或浏览器的多种方法(四种方法)
2017/06/29 Javascript
bootstrap+jquery项目引入文件报错的解决方法
2018/01/22 jQuery
解决vue 绑定对象内点击事件失效问题
2018/09/05 Javascript
Vue2.0 v-for filter列表过滤功能的实现
2018/09/07 Javascript
js canvas实现画图、滤镜效果
2018/11/27 Javascript
js对象简介与基本用法示例
2020/03/13 Javascript
[56:47]Ti4 循环赛第三日 iG vs Liquid
2014/07/12 DOTA
Django中针对基于类的视图添加csrf_exempt实例代码
2018/02/11 Python
numpy 对矩阵中Nan的处理:采用平均值的方法
2018/10/30 Python
Pandas Shift函数的基础入门学习笔记
2018/11/16 Python
python 实现屏幕录制示例
2019/12/23 Python
pyinstaller打包单文件时--uac-admin选项不起作用怎么办
2020/04/15 Python
用 Python 制作地球仪的方法
2020/04/24 Python
Python实现列表索引批量删除的5种方法
2020/11/16 Python
CSS3解决移动页面上点击链接触发色块的问题
2016/06/03 HTML / CSS
英国珠宝钟表和家居礼品精品店:David Shuttle
2018/02/24 全球购物
法国包包和行李箱销售网站:Bagage24.fr
2020/03/24 全球购物
如何开启linux的ssh服务
2013/06/03 面试题
安全事故检讨书
2014/01/18 职场文书
《少年王冕》教学反思
2014/04/11 职场文书
《吃水不忘挖井人》教学反思
2014/04/15 职场文书
查摆问题对照检查材料
2014/08/28 职场文书
党员争先创优承诺书
2015/01/20 职场文书
保研推荐信范文
2015/03/25 职场文书
Python趣味实战之手把手教你实现举牌小人生成器
2021/06/07 Python
Python使用mitmproxy工具监控手机 下载手机小视频
2022/04/18 Python