Skip to content

Commit 4552c98

Browse files
committed
Add Delay & Fix Get Posts Error
1 parent 297b2bd commit 4552c98

File tree

3 files changed

+34
-13
lines changed

3 files changed

+34
-13
lines changed

app.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@ const program = new Command();
66

77
program.version('1.0.0');
88
program.option('-u, --username <username>', 'velog 유저이름');
9+
program.option('-d, --delay <ms>', '요청 딜레이 시간')
910

1011
program.parse(process.argv);
1112

1213
!fs.existsSync('./backup') && fs.mkdirSync('./backup');
1314
!fs.existsSync('./backup/content') && fs.mkdirSync('./backup/content');
1415
!fs.existsSync('./backup/images') && fs.mkdirSync('./backup/images');
1516

16-
const crawler = new Crawler(program.username);
17+
18+
19+
const crawler = new Crawler(program.username, {
20+
delay: program.delay || 0,
21+
});
1722

1823
console.log('📙 백업을 시작합니다 / velog-backup')
1924
crawler.parse()

crawler/index.js

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,21 @@ const { join } = require('path');
55
const { PostsQuery, PostQuery } = require('./query');
66

77
class Crawler {
8-
constructor(username) {
9-
this.username = username;
8+
constructor(username, { delay }) {
9+
this.username = username;
10+
11+
// options
12+
this.delay = delay;
1013

1114
this.__grahpqlURL = 'https://v2.velog.io/graphql';
1215
}
1316

1417
async parse() {
1518
const posts = await this.getPosts();
1619

17-
posts.map(async(postInfo, i) => {
20+
posts.map(async(postInfo, i) => {
21+
if (this.delay > 0) await new Promise(r => setTimeout(r, this.delay * i));
22+
1823
let post = await this.getPost(postInfo.url_slug);
1924
post.body = await this.getImage(post.body);
2025

@@ -26,6 +31,7 @@ class Crawler {
2631
async getPosts() {
2732
const url = `https://velog.io/@${this.username}`;
2833
let response;
34+
let posts = [];
2935

3036
try {
3137
await axios.get(url);
@@ -38,14 +44,21 @@ class Crawler {
3844
console.error(e);
3945
}
4046

41-
try {
42-
response = await axios.post(this.__grahpqlURL, PostsQuery(this.username));
43-
} catch(e) {
44-
console.error(`⚠️ 벨로그에서 글 목록을 가져오는데 실패했습니다. \n error = ${e}`);
45-
process.exit(1);
47+
while (true) {
48+
try {
49+
if (response && response.data.data.posts.length >= 20) {
50+
response = await axios.post(this.__grahpqlURL, PostsQuery(this.username, posts[posts.length - 1].id));
51+
} else {
52+
response = await axios.post(this.__grahpqlURL, PostsQuery(this.username));
53+
}
54+
} catch(e) {
55+
console.error(`⚠️ 벨로그에서 글 목록을 가져오는데 실패했습니다. \n error = ${e}`);
56+
process.exit(1);
57+
}
58+
59+
posts = [...posts, ...response.data.data.posts];
60+
if (response.data.data.posts.length < 20) break;
4661
}
47-
48-
const posts = response.data.data.posts;
4962

5063
console.log(`✅ ${this.username}님의 모든 글(${posts.length} 개) 을 가져옴`);
5164

@@ -89,7 +102,9 @@ class Crawler {
89102
method: 'get',
90103
url,
91104
responseType: 'stream'
92-
}).then(resp => resp.data.pipe(fs.createWriteStream(path)));
105+
})
106+
.then(resp => resp.data.pipe(fs.createWriteStream(path)))
107+
.catch(e => console.error(`⚠️ 이미지를 다운 받는데 오류가 발생했습니다 / url = ${url} , e = ${e}`));
93108

94109
return `![](/images/${filename})`;
95110
});

crawler/query.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
const PostsQuery = (username) => ({
1+
const PostsQuery = (username, cursor = null) => ({
22
operationName:'Posts',
33
variables: {
44
username,
55
tag: null,
6+
cursor,
67
},
78

89
query: `query Posts($cursor: ID, $username: String, $temp_only: Boolean, $tag: String, $limit: Int) {

0 commit comments

Comments
 (0)