Hitokoto.us(一言)的 API 爬虫

爬虫一向都很有意思,当你把想要的内容从网络中抓取并保存下来的时候,一定会得到“占有”它的满满的幸福感 (๑´ڡ`๑)

大部分爬虫是很繁琐的,需要手动写出许多规则来过滤大部分的无效内容;有些就很简单了,可以通过网站提供的 API 来获取信息,这也是为开发者们提供的便利。本文主要记录爬取 一言 - ヒトコト 站点 API 的过程。

爬虫目标

爬取通过 API 能够得到的所有内容,基于 Node.js 。

内容存取

使用 MongoDB 存储数据,mongoose 操作数据。

代码主体

首先访问一次 API 地址:http://api.hitokoto.us/rand,看看它到底提供了哪些数据(手动格式化了一下):

1
2
3
4
5
6
7
8
9
10
{
"hitokoto": "我从小就害怕虫子",
"cat": "g",
"author": "firo",
"source": "小小闲",
"like": 9,
"date": "2012.07.22 12:02:01",
"catname": "其他",
"id": 1342929721000
}

随后就能组织写入数据库的数据结构了,与上述 json 数据格式保持一致,保存并命名为 hitokoto.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// 新建 Schema
var hitokotoSchema = new Schema({
hitokoto: String,
cat: String,
author: String,
source: String,
like: Number,
date: String,
catname: String,
_id: Number
});

// 导出 model
module.exports = mongoose.model('Hitokoto', hitokotoSchema);

然后新建 index.js 文件,导入上面的数据模型,获取 API 信息并根据已经组织好的数据结构写入数据库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
var Hitokoto = require('./hitokoto');
var mongoose = require('mongoose');
var http = require('http');

// 连接数据库,首先确保已在本地运行 mongod
mongoose.connect('mongodb://localhost/hitokoto');
mongoose.connection.on('error', function () {
console.log('mongodb connection error');
});

// 循环发送 GET 请求
// 不用 setTimeout,任性,可能造成的问题暂时不管了 XD
setInterval(function () {
http.get('http://api.hitokoto.us/rand', function (res) {
res.on('data', function (chunk) {
// 以 JSON 格式取得数据
data = JSON.parse(chunk);
// 查询获取到的数据是否已经写入数据库
Hitokoto.find({_id: data.id}, function (err, current) {
if (err) return console.log(err);

// 是则立即返回,进行下一次读取
if (current.length != 0) return;
// 否则将新数据写入数据库
var hitokoto = new Hitokoto({
hitokoto: data.hitokoto,
cat: data.cat,
author: data.author,
source: data.source,
like: data.like,
date: data.date,
catname: data.catname,
_id: data.id
});

hitokoto.save(function (err) {
if (err) return console.log(err);
console.log(data.id + ' saved!');
});
});
});
}).on('error', function (err) {
console.log(err);
})
}, 1500); // 读取时间间隔1.5秒

最后应该就可以正常运行了,保存成功的 id 值会在终端进行输出:

1
2
npm install mongoose
node index.js

截止到目前为止,共获取到 483 条一言的数据,可能还有几条,也可能没有了,不知道有没有办法知道是否全部爬完,或者有更高效的方法进行爬取?

其实本想把一言这么好玩的东西放进博客的,无奈审美太渣,感觉放哪儿都不好看,还是不破坏主题了,就这样吧 233

– EOF –