NodeJS 网络爬虫


前言

以前做网络爬虫都是用java开发,基于http client模拟请求,获取数据,然后基于正则表达式来提取需要的数据。这两天突然看见可以用NodeJS来做网络爬虫,而且最大的好处是,获取到的内容可以使用jQuery等库来解析操作dom,这个无疑对于数据提取是比较方便的。这里做个demo项目,作为以后应用的种子项目。

NodeJS 网络爬虫

转载请注明出处:http://www.haomou.net/2014/07/29/2014_nodejs_2/

准备相关类库

大致规划如下:

  1. web项目,基于express3, ejs模板
  2. 通过request抓取网页
  3. 通过jQuery, jsdom, htmlparser提取网页内容
    首先按照 NodeJS Express运行实例上的方法创建一个Express工程。然后安装相应的依赖包。

安装jsdom

执行如下命令安装,同时更新package.json

1
npm install jsdom --save-dev

这个安装的时候可能会报如下错误:

1
2
3
4
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! D:/project/expressjs/npm-debug.log
npm ERR! not ok code 0

这是由于缺少安装依赖环境。这里不只是jsdom,很多其他的插件包,很多也是需要这个依赖环境的。这个依赖环境其实就是一个编译环境,因为有些插件包是一源码形式发布的,安装时候需要对代码进行编译。所以这里需要安装:

  1. python 2.7版本,这个版本最好不要太高。
  2. Visual C++ 2010 Express,这个主要安装c++编译器
  3. 安装node-gyp编译插件,npm install -g node-gyp
    然后就可以安装jsdom了。

安装jQuery,xmlhttprequest,request,htmlparser

依次安装并更新package.json:

1
2
3
4
npm install jQuery --save-dev
npm install xmlhttprequest --save-dev
npm install request --save-dev
npm install htmlparser --save-dev

爬虫实例

假设我们现在要去官网爬取彩票的开奖数据,以百度乐彩(http://baidu.lecai.com/lottery/draw/?agentId=5571 )网站为例,我们要抓取双色球的开奖数据。
NodeJS 网络爬虫
首先在项目目录下增加myUtil.js,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
var MyUtil = function () {
};
var http = require('http');
var request = require('request');
MyUtil.prototype.get=function(url,callback){
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
callback(body,response.statusCode);
}
})
}
module.exports = new MyUtil();

然后修改 routes/index.js文件,代码如下:

1
2
3
4
5
6
7
8
9
10
var myUtil = require('../myUtil.js');
var $ = require('jQuery');
exports.index = function(req, res){
var url="http://baidu.lecai.com/lottery/draw/?agentId=5571";
console.log(url);
myUtil.get(url,function(content,status){
console.log("status:="+status);
res.send(content);
});
};

这里我们已经把获取到的网页内容的content输出到了本地,启动应用,打开浏览器:http://127.0.0.1:3000 可以看见本地显示的和原网页的一模一样。然后我们就可以提取需要的内容。
首先通过使用浏览器调试开发工具(按F12),来查找我们需要的数据所在的位置。如下:
NodeJS 网络爬虫
然后我们通过使用css选择器来选中这块内容,通过jquery来处理。修改routes/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var myUtil = require('../myUtil.js');
var $ = require('jQuery');
exports.index = function(req, res){
var url="http://baidu.lecai.com/lottery/draw/?agentId=5571";
console.log(url);
myUtil.get(url,function(content,status){
console.log("status:="+status);
var ssqnum=[];
$('.ballbg:first .ball_1,.ballbg:first .ball_2').each(function(k,v){
ssqnum.push($(v).html());
})
console.log(ssqnum);
res.send(content);
});
};

需要注意的是这里面,如果用css选择器,选中双色球的数据列表的选择器为.ballbg:first-child,但是使用jQuery的语法$(‘.ballbg:first-child’)选取不到第一个列表数据,因为这里面有个区别,jQuery里面有自己的选择器,选取第一个元素是:first,于是正确的jQuey选择器语句是$(‘.ballbg:first’),执行结果:

1
2
3
4
5
6
7
8
9
10
11
12
$('.ballbg:first')
[
<div class=​"ballbg">​
<span class=​"ball_1">​05​</span>​
<span class=​"ball_1">​06​</span>​
<span class=​"ball_1">​08​</span>​
<span class=​"ball_1">​14​</span>​
<span class=​"ball_1">​22​</span>​
<span class=​"ball_1">​31​</span>​
<span class=​"ball_2">​08​</span>​
</div>​
]

然后就是提取其中的数据。

1
2
3
4
5
var ssqnum=[];
$('.ballbg:first .ball_1,.ballbg:first .ball_2').each(function(k,v){
ssqnum.push($(v).html());
})
console.log(ssqnum); //["05", "06", "08", "14", "22", "31", "08"]

谢谢!

欢迎关注皓眸学问公众号(扫描左侧二维码),每天好文、新技术!任何学习疑问或者工作问题都可以给我留言、互动。T_T 皓眸大前端开发学习 T_T

未经允许不得转载:皓眸大前端 » NodeJS 网络爬虫

赞 (0)
分享到:更多 ()

评论 0