[分享]用NodeJs做一个小爬虫,附源码!

前言

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

蠢蠢欲动

抛开机器学习这种貌似很高大上的数据处理技术,单纯的做一个爬虫获取数据还是非常简单的。对于前段er们来说,生在有nodejs的年代真是不要太幸福了,下面就用nodejs来做一个爬虫吧。

这次我们先拿CSDN来练练手,爬妹子什么的,其实大同小异。要实现的功能就是爬取前端板块的博文,输出作者的信息。

首先是工具的准备,nodejs当然是必须要装好的,我这里用的是目前最新版的6.2.0版本。另外由于我们需要通过各种http请求去爬取内容,所以一个好用的http调试工具也是必需的,这里我推荐是用postman。

搭建环境

根据爬虫需要的功能确定我们要使用的第三方库:

后端服务: express
发出http请求: superagent
控制并发请求:async + eventproxy
分析网页内容:cheerio
相关库的 API 请到对应的 GitHub 项目页上去了解,这里我就不再赘述了,对应的 package.json :

{
"name": "spider",
"version": "0.0.0",
"description": "learn nodejs on github",
"scripts": {

"start": "node app.js"

},
"dependencies": {

"async": "^2.0.0-rc.6","cheerio": "^0.20.0","eventproxy": "^0.3.4","express": "^4.9.5","superagent": "^2.0.0"

},
}

写好的 package 记得安装下,这样我们就搭好了开发环境。

爬虫主体

下面按照爬虫需要的功能来一步步写爬虫主体。

后台服务部分

实现的功能是接收前端请求启动爬虫,完成信息爬取之后将信息返回给前端。后台服务部分我这里使用了 express 框架,这里比较简单也可以使用原生的 http 模块。简单框架如下:

var express = require('express');var app = express();app.get('/', function (req, res, next) {    // your code here});app.listen(3000, function (req, res) {    console.log('app is running at port 3000');});

在 get 处理中插入我们的响应代码,包括启动爬虫,结果信息输出等。

文章链接的爬取

这里我们用到的是 superagent 这个库来实现,此库作者是个多产大神,我们这里用到的库基本都是他写的,颤抖吧、少年们!

superagent.get(Url).end(function (err, res) {    if (err) { return next(err); }    // your code here});

Url 为我们请求的地址,使用 get 的方式请求,其实效果跟你用浏览器打开 Url 的效果是一样的,返回来的数据都放在 res 中,对 res 分析就可以得到我们想要的数据了。

数据的处理

这里我们用到的是 cheerio 这个库,他可以让我们以 jQuery 的方式操作返回的数据,实在太贴心了。

// 提取作者博客链接,注意去重var $ = cheerio.load(sres.text);$('.blog_list').each(function (i, e) {    var u = $('.user_name', e).attr('href');    if (authorUrls.indexOf(u) === -1) {        authorUrls.push(u);    }});

是不是很熟悉的感觉? 完全就是 jQuery 的语法呀。

文章作者信息的爬取

这里我们要进入作者主页去爬取相应的消息,跟上一步爬取链接是一样的。

superagent.get(authorUrl)    .end(function (err, ssres) {        if (err) { callback(err, authorUrl + ' error happened!'); }        var $ = cheerio.load(ssres.text);        var result = {            userId: url.parse(myurl).pathname.substring(1),            blogTitle: $("# blog_title a").text(),            visitCount: parseInt($('# blog_rank>li').eq(0).text().split(/[::]/)[1]),            score: parseInt($('# blog_rank>li').eq(1).text().split(/[::]/)[1]),            oriCount: parseInt($('# blog_statistics>li').eq(0).text().split(/[::]/)[1]),            copyCount: parseInt($('# blog_statistics>li').eq(1).text().split(/[::]/)[1]),            trsCount: parseInt($('# blog_statistics>li').eq(2).text().split(/[::]/)[1]),            cmtCount: parseInt($('# blog_statistics>li').eq(3).text().split(/[::]/)[1])        };        callback(null, result);    });

这里我们是用 callback 返回结果的。

并发的控制

因为我们的请求都是异步的,所以需要执行成功的回调函数中执行下一步操作,在多并发的情况下,就需要一个计数器来判断是否所有并发均已成功执行完。这里用到的是 eventproxy 这个库来替我们管理并发结果。

CSDN上web前端有3页,所以我们要执行 3 次爬取文章链接,用 eventproxy 的写法就是:

var baseUrl = 'http://blog.csdn.net/web/index.html';var pageUrls = [];for (var _i = 1; _i http://localhost:3000 查看结果:可以看到在返回中的body中已经将我们需要的数据返回来了。 至此,我们的小爬虫就完成了,是不是很简单呢?**完整的代码**

/ *

  • Created by justeptech on 2016/7/11.
    */

var cheerio = require('cheerio');
var superagent = require('superagent');
var async = require('async');
var url = require('url');

var express = require('express');
var app = express();

var eventproxy = require('eventproxy');
var ep = eventproxy();

var baseUrl = 'http://blog.csdn.net/web/index.html';
var pageUrls = [];
for (var _i = 1; _i li').eq(0).text().split(/[::]/)[1]),
score: parseInt($('# blog_rank>li').eq(1).text().split(/[::]/)[1]),
oriCount: parseInt($('# blog_statistics>li').eq(0).text().split(/[::]/)[1]),
copyCount: parseInt($('# blog_statistics>li').eq(1).text().split(/[::]/)[1]),
trsCount: parseInt($('# blog_statistics>li').eq(2).text().split(/[::]/)[1]),
cmtCount: parseInt($('# blog_statistics>li').eq(3).text().split(/[::]/)[1])
};
callback(null, result);
});

    };    // 控制最大并发数为5,在结果中取出callback返回来的整个结果数组。    async.mapLimit(authorUrls, 5, function (myurl, callback) {        fetchUrl(myurl, callback);    }, function (err, result) {        console.log('=========== result: ===========\n', result);        res.send(result);    });});// 获取每页的链接数组,这里不要用emit返回了,因为我们获得的已经是一个数组了。pageUrls.forEach(function (page) {    superagent.get(page).end(function (err, sres) {        // 常规的错误处理        if (err) {            return next(err);        }        // 提取作者博客链接,注意去重        var $ = cheerio.load(sres.text);        $('.blog_list').each(function (i, e) {            var u = $('.user_name', e).attr('href');            if (authorUrls.indexOf(u) === -1) {                authorUrls.push(u);            }        });        console.log('get authorUrls successful!\n', authorUrls);        ep.emit('get_topic_html', 'get authorUrls successful');    });});

});

app.listen(3000, function (req, res) {
console.log('app is running at port 3000');
});

关于Nodejs搭建小爬虫的介绍就到这里了,码字不易,顺手点赞哈!本文源自WeX5论坛,原文链接:http://bbs.wex5.com/forum.php...#node.js、Github#

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部