search.js
8.08 KB
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
146
147
148
149
const Discord = require("discord.js");
exports.run = async (client, msg, args, prefix) => {
if (args[0]) { // 명령어 뒤에 입력값이 있을 경우 (ex. !<명령어> <채팅>)
// 검색어 한 문장으로 합치기
const search = args.join(' ');
// console.log(search);
// 각 사이트별 제품 검색
const puppeteer = require('puppeteer'); //include Puppeteer Library
puppeteer.launch({headless:true}).then(async browser => {
// 브라우저 열기
const page = await browser.newPage();
console.log('Open Browser');
// 1. 베스트펜
try {
console.log("bestpen crawling");
await page .goto('http://www.bestpen.kr');
// 검색창으로 이동 & search 검색
await page.waitForSelector('#header > div.headerBtm > div > p.searchOpen > i');
await page .click('#header > div.headerBtm > div > p.searchOpen > i');
await page .type('#keyword', search);
await page .keyboard.press( "Enter" );
// await page.screenshot({ path : "screenshot.png" });
} catch { ; } // 사이트 링크에 이상이 생겼거나 검색에 문제가 생겼을 경우 프로그램이 종료되는 것을 방지
// 검색 결과 가져오기 (최대 4개)
var bestpen = '';
for (var i = 1; i <= 4; i++) {
try {
var title = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-name > a');
var bestpen_title = await page.evaluate( title => title.textContent, title );
// console.log("베스트펜 검색 결과 제품명 : ", bestpen_title);
var link = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dt > a');
var bestpen_link = await page.evaluate( link => link.href, link );
// console.log("베스트펜 검색 링크 : ", bestpen_link);
// 링크 구조상 &search 뒷부분은 제품 링크를 띄우는데 영향을 미치지 않음
// -> 글자수 제한(1024)도 있으므로 제거
bestpen_link = bestpen_link.slice(0, bestpen_link.indexOf('&search'));
try {
var price = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-price > p:nth-child(2) > span.price');
var bestpen_data = await page.evaluate( price => price.textContent, price );
// console.log("베스트펜 검색 결과 가격 : ", bestpen_data);
} catch {
// 품절이라서 금액정보가 없을 경우 "SOLD OUT"으로 표시
bestpen_data = "SOLD OUT";
}
bestpen += `[${bestpen_title}](${bestpen_link}) - ${bestpen_data}` + '\n';
} catch {
if (i == 1) {
// 제품 정보가 아예 없을 경우 "검색결과 없음"으로 표시
bestpen += "검색결과 없음" + '\n';
break;
} else {
// 제품 개수가 4개 이하인 경우
break;
}
}
}
// 2. 펜카페
try {
console.log("pencafe crawling");
await page .goto('http://www.pencafe.co.kr');
// search 검색
await page.waitForSelector('#header > div.hd_mib > div.hd_sch.f_left > form > fieldset > input');
await page .type('#header > div.hd_mib > div.hd_sch.f_left > form > fieldset > input', search);
await page .keyboard.press( "Enter" );
// await page.screenshot({ path : "screenshot.png" });
} catch { ; } // 사이트 링크에 이상이 생겼거나 검색에 문제가 생겼을 경우 프로그램이 종료되는 것을 방지
// 검색 결과 가져오기 (최대 4개)
var pencafe = '';
for (var i = 1; i <= 4; i++) {
try {
var title = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-name > a');
var pencafe_title = await page.evaluate( title => title.textContent, title );
// console.log("펜카페 검색 결과 제품명 : ", pencafe_title);
// 펜카페 구조상 제품명 앞에 할인률(ex. 17%)이 붙는 경우가 많음 -> 제거
if (pencafe_title.indexOf('%') != -1) { pencafe_title = pencafe_title.slice(pencafe_title.indexOf('%')+1); }
// 펜카페 구조상 제품명 뒤에 사족(ex. (색상선택/금장~~~))이 붙는 경우가 많음 -> 제거
if (pencafe_title.indexOf('(') != -1) { pencafe_title = pencafe_title.slice(0, pencafe_title.lastIndexOf('(')); }
var link = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-name > a');
var pencafe_link = await page.evaluate( link => link.href, link );
// console.log("펜카페 검색 링크 : ", pencafe_link);
// 링크 구조상 &search 뒷부분은 제품 링크를 띄우는데 영향을 미치지 않음
// -> 글자수 제한(1024)도 있으므로 제거
pencafe_link = pencafe_link.slice(0, pencafe_link.indexOf('&search'));
try {
var price = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-price > span');
var pencafe_data = await page.evaluate( price => price.textContent, price );
// console.log("펜카페 검색 결과 가격 : ", pencafe_data);
} catch {
// 품절이라서 금액정보가 없을 경우 "SOLD OUT"으로 표시
pencafe_data = "SOLD OUT";
}
pencafe += `[${pencafe_title}](${pencafe_link}) - ${pencafe_data}` + '\n';
} catch {
if (i == 1) {
// 제품 정보가 아예 없을 경우 "검색결과 없음"으로 표시
pencafe += "검색결과 없음" + '\n'
break;
} else {
// 제품 개수가 4개 이하인 경우
break;
}
}
}
// 브라우저 닫기
await browser.close();
console.log('Browser Closed');
// 검색 결과 챗봇에 출력
let Commands = new Discord.MessageEmbed()
.setTitle(`${search}에 대한 검색 결과`)
.setColor("E5D49A")
// 베스트펜 검색 결과 (ex. 제품명(링크) - 금액)
.addField('베스트펜', `${bestpen.slice(0, 1023)}`)
// 펜카페 검색 결과
.addField('펜카페', `${pencafe.slice(0, 1023)}`)
msg.reply({ embeds: [Commands] });
});
// 검색 대기 시간이 길어질 수 있으므로 사용자에게 진행상황을 알려줄 필요가 있다
msg.reply("검색중 ...");
} else {
msg.reply("검색어가 없습니다. 검색어를 추가해서 다시 입력해주세요.");
}
};
exports.config = {
name: '문구',
aliases: ['문구류', '가격비교', 'stationery', 'search'],
category: ['stationery'],
des: ['채팅 내용에 대한 검색결과를 보여줍니다.'],
use: ['!문구 <채팅>']
};