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入门详解(多篇文章结合)
Mar 07 NodeJs
跟我学Nodejs(一)--- Node.js简介及安装开发环境
May 20 NodeJs
nodejs 提示‘xxx’ 不是内部或外部命令解决方法
Nov 20 NodeJs
Nodejs express框架一个工程中同时使用ejs模版和jade模版
Dec 28 NodeJs
用nodejs的实现原理和搭建服务器(动态)
Aug 10 NodeJs
nodejs中全局变量的实例解析
Mar 07 NodeJs
实例分析nodejs模块xml2js解析xml过程中遇到的坑
Mar 18 NodeJs
nodeJS实现简单网页爬虫功能的实例(分享)
Jun 08 NodeJs
使用vs code开发Nodejs程序的使用方法
Sep 21 NodeJs
nodejs的路径问题的解决
Jun 30 NodeJs
详解webpack打包nodejs项目(前端代码)
Sep 19 NodeJs
Nodejs环境实现socket通信过程解析
Jul 03 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
php遍历所有文件及文件夹的方法深入解析
2013/06/08 PHP
一个简单的php加密解密函数(动态加密)
2013/06/19 PHP
PHP使用DOMDocument类生成HTML实例(包含常见标签元素)
2014/06/25 PHP
使用ob系列函数实现PHP网站页面静态化
2014/08/13 PHP
带你了解PHP7 性能翻倍的关键
2015/11/19 PHP
jQuery点击后一组图片左右滑动的实现代码
2012/08/16 Javascript
jQuery文本框(input textare)事件绑定方法教程
2013/04/24 Javascript
Jquery创建层显示标题和内容且随鼠标移动而移动
2014/01/26 Javascript
jquery、js操作checkbox全选反选
2014/03/12 Javascript
jquery实现叠层3D文字特效代码分享
2015/08/21 Javascript
js实现拉幕效果的广告代码
2015/09/02 Javascript
自动化测试读写64位操作系统的注册表
2016/08/15 Javascript
深入浅析JS是按值传递还是按引用传递(推荐)
2016/09/18 Javascript
微信小程序中form 表单提交和取值实例详解
2017/04/20 Javascript
AngularJS select设置默认值的实现方法
2017/08/25 Javascript
nodejs微信扫码支付功能实现
2018/02/17 NodeJs
vue对storejs获取的数据进行处理时遇到的几种问题小结
2018/03/20 Javascript
闭包在python中的应用之translate和maketrans用法详解
2014/08/27 Python
Python编写生成验证码的脚本的教程
2015/05/04 Python
python 查找字符串是否存在实例详解
2017/01/20 Python
python实战之实现excel读取、统计、写入的示例讲解
2018/05/02 Python
详解Python并发编程之创建多线程的几种方法
2019/08/23 Python
Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】
2019/10/12 Python
Python 基于FIR实现Hilbert滤波器求信号包络详解
2020/02/26 Python
python tkinter的消息框模块(messagebox,simpledialog)
2020/11/07 Python
详解CSS3阴影 box-shadow的使用和技巧总结
2016/12/03 HTML / CSS
浅谈HTML5新增及移除的元素
2016/06/27 HTML / CSS
秘鲁购物网站:Linio秘鲁
2017/04/07 全球购物
FragranceNet中文网:北美健康美容线上零售商
2020/08/26 全球购物
音乐表演专业毕业生求职信
2013/10/14 职场文书
省级优秀班集体申报材料
2014/05/25 职场文书
2014年街道办事处工作总结
2014/12/11 职场文书
2015应届毕业生求职信范文
2015/03/20 职场文书
实习感想范文
2015/08/10 职场文书
Mysql事务索引知识汇总
2022/03/17 MySQL
使用CSS实现音波加载效果
2023/05/07 HTML / CSS