-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
145 lines (116 loc) · 3.41 KB
/
index.js
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
const got = require('got');
const host = 'https://time.geekbang.org/serv/v1';
const links = {
login: 'https://account.geekbang.org/account/ticket/login',
products: `${host}/my/products/all`,
productList: `${host}/my/products/list`,
intro: `${host}/column/intro`,
articles: `${host}/column/articles`,
article: `${host}/article`,
comments: `${host}/comments`,
audios: `${host}/column/audios`,
};
const CN_CODE = '86';
async function request(link, body = {}, cookie = '') {
const headers = {
Referer: 'https://servicewechat.com/wxc4f8a61ef62e6e35/20/page-frame.html',
Cookie: cookie,
};
try {
const isLoginLink = link === links.login;
const res = await got(link, {
json: true, headers, body, method: 'post',
});
const loginCookie = isLoginLink
? res.headers['set-cookie'].map(v => v.split(';')[0]).join('; ')
: '';
if (res.body.code === 0) {
return isLoginLink
? { ...res.body.data, cookie: loginCookie }
: res.body.data;
}
throw new Error(`Wrong Code: ${res.body.code}`);
} catch (err) {
throw err;
}
}
class Geektime {
constructor(country, cellphone, password) {
let countryCode = country;
let phone = cellphone;
let pass = password;
if (password === undefined) {
[countryCode, phone, pass] = [CN_CODE, country, cellphone];
}
if (typeof phone !== 'string' || typeof pass !== 'string') {
throw new TypeError('cellphone/password should be string');
}
if (phone === '' || pass === '') {
throw new Error('cellphone/password should not be empty');
}
this.country = +countryCode;
this.cellphone = phone;
this.password = pass;
this.cookie = null;
}
// 产品列表,返回 专栏/视频课/微课/其他
async products() {
const cookie = await this.getCookie();
const res = await request(links.products, null, cookie);
// only return 10, we need more!
const parts = res.filter(v => v.page.more);
const fulls = await Promise.all(
parts.map(v => request(
links.productList, { nav_id: v.id, prev: 0, size: 1000 }, cookie,
)),
);
fulls.forEach((v, index) => {
res.find(m => parts[index].id === m.id).list = v.list;
});
return res;
}
// 专栏介绍
async intro(cid) {
const cookie = await this.getCookie();
return request(links.intro, { cid }, cookie);
}
// 专栏文章列表
async articles(cid, size = 1000) {
const cookie = await this.getCookie();
return request(links.articles, { cid, size }, cookie);
}
// 单篇文章详情
async article(id) {
const cookie = await this.getCookie();
return request(links.article, { id }, cookie);
}
// 文章评论
async comments(aid, size = 200, prev = 0) {
const cookie = await this.getCookie();
return request(links.comments, { aid, size, prev }, cookie);
}
// 音频列表
async audios(cid, size = 1000) {
const cookie = await this.getCookie();
return request(links.audios, { cid, size }, cookie);
}
async getCookie() {
if (this.cookie) {
return this.cookie;
}
const { cellphone, password, country } = this;
const body = {
cellphone,
password,
country,
remember: 1,
captcha: '',
platform: 4,
appid: 1,
};
const { cookie } = await request(links.login, body);
this.cookie = cookie;
return this.cookie;
}
}
module.exports = Geektime;