用nodejs去爬一下A站老司机的文章

自从node问世以后,就不断被JavaScript的忠实追随者拿来干一些原来只有php、Python等后端语言才能干的事情,例如写个爬虫之类的。对于前端er来说,用上一些好用的轮子,你可能十几行代码就可以写一个crawler哦~

爬虫的思路十分简单:

  1. 按照一定的规律发送 HTTP 请求获得页面 HTML 源码(必要时需要加上一定的 HTTP 头信息,比如 cookie 或 referer 之类)
  2. 利用正则匹配或第三方模块解析 HTML 代码,提取有效数据
  3. 将数据持久化到数据库中

当然爬虫的写法千千万,下面只提供吃瓜群众都能看懂的版本~

假定你已经有了一定的nodeJS基础,如果没有请移步围观=>LV触手系列:前端之魂,触碰后端的手——Node.js学习之路(一)


*准备阶段*

NPM

(npm:趁还没被yarn干掉再续一秒)

首先我们需要通过npm安装两个模块reuqestcheerio来帮助我们更方便地请求解析页面

终端cd到你的文件目录里,先装上,一会儿我再各自讲它们

1
2
$npm install request --save
$npm install cheerio --save

package.json

装完你可以看到你文件夹里的package.json里已经多了两个依赖项

1
2
3
4
5
6
7
8
{
"name": "crawler",
"version": "0.0.1",
"dependencies": {
"request": "^2.75.0",
"cheerio": "^0.22.0"
}
}

crawler.js

假设你的爬虫程序主文件名叫crawler.js,我们需要在这个文件里引入requestcheerio这两个模块
js代码为

1
2
var request = require("request");
var cheerio = require("cheerio");

准备阶段完成后,让我们开始沉迷于学习阶段= =


*学习阶段*

REQUEST

request是个非常好用的针对HTTP请求的模块,简言之是对 http.request更高级的封装,口号是——“Simplified HTTP client”

request 这个模块可以帮你下载资料。使用方式:

1
2
3
4
5
6
7
request({
url: "你想抓的网址",
method: "GET"
}, function(e,r,b) { /* Callback 函式*/
/* e: 错误代码*/
/* b: 传回的资料内容*/
});

随便来个例子,假设你觉得你自己真是沉迷于学习无法自拔,是我的迷妹/痴汉一只,你想要随时监控我博客的内容,那你就这样写

1
2
3
4
5
6
request({
url: "http://goodluckforever.github.io",
method: "GET"
}, function(e,r,b) {
if(!e) console.log(b);
});

不过我建议你们转去搞LV的( ͡° ͜ʖ ͡°)=>群疯之下

CHEERIO

cheerio模块可以在服务器端像使用Jquery的方式一样操作Dom结构,许多用法和jquery 的语法基本相同,为服务器特别定制的,快速、灵活、实施的jQuery核心实现。
简言之,是服务器端的鸡块瑞(◕ܫ◕)~

Cheerio 几乎能够解析任何的 HTML 和 XML document,灵活好用,灰常厉害
只需这么用:

1
2
3
4
5
6
7
8
9
10
11
//load里面是要加载的html字符串
var $ = cheerio.load('<h2 class="title">Hello world</h2>')
//text()方法可以将字符串写入标签
$('h2.title').text('Hello there!')
//添加类也跟鸡块瑞一样
$('h2').addClass('welcome')
//最终就会输出想要的啦
$.html()
//=> <h2 class="title welcome">Hello there!</h2>

基础知识学习完毕,让我们一起投入到火热的社会主义建设中去~


*建设阶段*

先把request搞上去,明确要爬的页面,我们要爬的是A站的文章区(我不想搞B站,不想被封号TAT)

1
2
3
4
5
6
7
8
9
10
11
request({
//老司机地址
url: "http://www.acfun.tv/v/list110/index.htm",
//请求方式
method: "GET"
}, function(e,r,b) { //回调函数
//如果错误或没有资料就返回
if(e || !b) { return; }
//如果正确我们就拍拍手
//……
})

我们当然不能拍拍手,我们要用cheerio去解析我们刚请求成功的页面

1
2
3
4
5
6
7
8
9
10
11
12
13
,function(e,r,b) {
if(e || !b) { return; }
/*正确的情况*/
var $ = cheerio.load(b);//b就是我们请求成功的页面
//搞个数组用于存放爬下来的内容
var result = [];
//选择器里就是你从控制台里看到的标题的源码
var titles = $(".mainer .item a.title");
//遍历并添加在数组里
for(var i=0;i<titles.length;i++) {
result.push($(titles[i]).text());
}
})

最后爬下来的结果我们把它放在result.json文件里

1
2
//首先要引入fs模块,fs是node内置的模块,提供本地文件的读写能力
var fs = require("fs");

最后把这句话放在request方法里

1
fs.writeFileSync("result.json", JSON.stringify(result));

最终你的crawler.js看起来是这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var fs = require("fs");
var request = require("request");
var cheerio = require("cheerio");
request({
url: "http://www.acfun.tv/v/list110/index.htm",
method: "GET"
}, function(e,r,b) {
if(e || !b) { return; }
var $ = cheerio.load(b);
var result = [];
var titles = $(".mainer .item a.title");
for(var i=0;i<titles.length;i++) {
result.push($(titles[i]).text());
}
fs.writeFileSync("result.json", JSON.stringify(result));
});

啊~麻麻~我用16行代码就写了个爬虫~╰(°▽°)╯
慢着,我们先来试验下是否能成功


*实验阶段*

cd 到你的目录,敲下激动人心的如下代码

1
$ node crawler

然后观察你的文件夹里是否多了个result.json呢,它看起来应该是如下这样充满了大新闻

result.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
"高校技术宅黑了全教学楼的电脑给妹子表白",
"【数据检查】ACFUN音乐投票新趋周榜.2016年第37期(总第40期)",
"AcFun三文鱼摄影群作品汇报 第四期",
"【设计文章】等角视轴小卖部过程拆解",
"五张动图,帮你了解三星Note7爆炸所有可能原因",
"三星Note7炸机机主:我觉得我是个傻子",
"脱欧了,涨价了,超市里英国人的“老干妈”没货了...这下英国人民怒了",
"越南网友选出了他们心中的亚洲最美女星",
"金庸武侠作品到了日本后的封面",
"麦当劳的各地特色菜 网友:越看越没食欲",
"国行苹果iPhone7 Plus部分现货:亮黑色仍全线缺货",
"71岁大爷痴迷CS:感觉病都好多了"
]

恭嘿累爬虫成功~想要爬到更深入的信息,就自己去看API吧~爬到什么不得了的东西的话,记得分享给我萌哦~(づ ̄3 ̄)づ╭❤~