Showing
1 changed file
with
170 additions
and
133 deletions
1 | const Discord = require("discord.js"); | 1 | const Discord = require("discord.js"); |
2 | exports.run = async (client, msg, args, prefix) => { | 2 | exports.run = async (client, msg, args, prefix) => { |
3 | if (args[0]) { // 명령어 뒤에 입력값이 있을 경우 (ex. !<명령어> <채팅>) | 3 | if (args[0]) { // 명령어 뒤에 입력값이 있을 경우 (ex. !<명령어> <채팅>) |
4 | - // 각 사이트별 제품 검색 | 4 | + // 검색어 한 문장으로 합치기 |
5 | - const puppeteer = require('puppeteer'); //include Puppeteer Library | 5 | + const search = args.join(' '); |
6 | - puppeteer.launch({headless:true}).then(async browser => { | 6 | + // console.log(search); |
7 | - // 브라우저 열기 | 7 | + |
8 | + // 검색 대기 시간이 길어질 수 있으므로 사용자에게 진행상황을 알려줄 필요가 있다 | ||
9 | + msg.reply("검색중 ..."); | ||
10 | + | ||
11 | + //include Puppeteer Library | ||
12 | + const puppeteer = require('puppeteer'); | ||
13 | + | ||
14 | + const withBrowser = async (fn) => { | ||
15 | + const browser = await puppeteer.launch({headless:true}); | ||
16 | + try { | ||
17 | + return await fn(browser); | ||
18 | + } finally { | ||
19 | + await browser.close(); | ||
20 | + } | ||
21 | + } | ||
22 | + | ||
23 | + const withPage = (browser) => async (fn) => { | ||
8 | const page = await browser.newPage(); | 24 | const page = await browser.newPage(); |
9 | - console.log('Open Browser'); | 25 | + try { |
26 | + return await fn(page); | ||
27 | + } finally { | ||
28 | + await page.close(); | ||
29 | + } | ||
30 | + } | ||
10 | 31 | ||
11 | - // 1. 베스트펜 | 32 | + const urls = ['http://www.bestpen.kr/shop/shopbrand.html?&search=', 'http://www.pencafe.co.kr/shop/shopbrand.html?&search=', 'https://blueblack.co.kr/product/search.html?&keyword=', 'http://japan9.co.kr/shop/shopbrand.html?&search=']; |
33 | + const results = await withBrowser(async (browser) => { | ||
34 | + return Promise.all(urls.map(async (url) => { | ||
35 | + return withPage(browser)(async (page) => { | ||
36 | + // 각 사이트별 제품 검색 | ||
37 | + var result = ''; | ||
38 | + site : switch(urls.indexOf(url)) { | ||
39 | + case 0: | ||
40 | + // 베스트펜 | ||
12 | try { | 41 | try { |
13 | - console.log("bestpen crawling"); | 42 | + var bestpen_url = url + search + "&sort=price" |
14 | - await page .goto('http://www.bestpen.kr'); | 43 | + await page.goto(bestpen_url); |
15 | - | 44 | + // console.log("bestpen crawling"); |
16 | - // 검색창으로 이동 & args[0] 검색 | 45 | + |
17 | - await page.waitForSelector('#header > div.headerBtm > div > p.searchOpen > i'); | 46 | + // 페이지 로딩 대기 |
18 | - await page .click('#header > div.headerBtm > div > p.searchOpen > i'); | 47 | + await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child(4) > dd > ul > li.prd-name > a'); |
19 | - await page .type('#keyword', args[0]); | ||
20 | - await page .keyboard.press( "Enter" ); | ||
21 | - // await page.screenshot({ path : "screenshot.png" }); | ||
22 | } catch { ; } // 사이트 링크에 이상이 생겼거나 검색에 문제가 생겼을 경우 프로그램이 종료되는 것을 방지 | 48 | } catch { ; } // 사이트 링크에 이상이 생겼거나 검색에 문제가 생겼을 경우 프로그램이 종료되는 것을 방지 |
23 | 49 | ||
24 | // 검색 결과 가져오기 (최대 4개) | 50 | // 검색 결과 가져오기 (최대 4개) |
25 | - var bestpen = ''; | 51 | + searchLoop : for (var i = 1; i <= 4; i++) { |
26 | - for (var i = 1; i <= 4; i++) { | ||
27 | try { | 52 | try { |
28 | - var title = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-name > a'); | 53 | + var title = await page.$eval('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-name > a', element => { |
29 | - var bestpen_title = await page.evaluate( title => title.textContent, title ); | 54 | + return element.textContent; |
30 | - // console.log("베스트펜 검색 결과 제품명 : ", bestpen_title); | 55 | + }); |
56 | + // console.log("베스트펜 검색 결과 제품명 : ", title); | ||
31 | 57 | ||
32 | - var link = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dt > a'); | 58 | + var link = await page.$eval('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dt > a', element => { |
33 | - var bestpen_link = await page.evaluate( link => link.href, link ); | 59 | + return element.href; |
34 | - // console.log("베스트펜 검색 링크 : ", bestpen_link); | 60 | + }); |
61 | + // console.log("베스트펜 검색 링크 : ", link); | ||
35 | 62 | ||
36 | // 링크 구조상 &search 뒷부분은 제품 링크를 띄우는데 영향을 미치지 않음 | 63 | // 링크 구조상 &search 뒷부분은 제품 링크를 띄우는데 영향을 미치지 않음 |
37 | // -> 글자수 제한(1024)도 있으므로 제거 | 64 | // -> 글자수 제한(1024)도 있으므로 제거 |
38 | - bestpen_link = bestpen_link.slice(0, bestpen_link.indexOf('&search')); | 65 | + link = link.slice(0, link.indexOf('&search')); |
39 | 66 | ||
40 | try { | 67 | try { |
41 | - 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'); | 68 | + var price = await page.$eval('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-price > p:nth-child(2) > span.price', element => { |
42 | - var bestpen_data = await page.evaluate( price => price.textContent, price ); | 69 | + return element.textContent; |
43 | - // console.log("베스트펜 검색 결과 가격 : ", bestpen_data); | 70 | + }); |
71 | + // console.log("베스트펜 검색 결과 가격 : ", price); | ||
44 | } catch { | 72 | } catch { |
45 | // 품절이라서 금액정보가 없을 경우 "SOLD OUT"으로 표시 | 73 | // 품절이라서 금액정보가 없을 경우 "SOLD OUT"으로 표시 |
46 | - bestpen_data = "SOLD OUT"; | 74 | + price = "SOLD OUT"; |
47 | } | 75 | } |
48 | 76 | ||
49 | - bestpen += `[${bestpen_title}](${bestpen_link}) - ${bestpen_data}` + '\n'; | 77 | + result += `[${title}](${link}) - ${price}` + '\n'; |
50 | } catch { | 78 | } catch { |
51 | if (i == 1) { | 79 | if (i == 1) { |
52 | // 제품 정보가 아예 없을 경우 "검색결과 없음"으로 표시 | 80 | // 제품 정보가 아예 없을 경우 "검색결과 없음"으로 표시 |
53 | - bestpen += "검색결과 없음" + '\n'; | 81 | + result += "검색결과 없음" + '\n'; |
54 | - break; | 82 | + break searchLoop; |
55 | } else { | 83 | } else { |
56 | // 제품 개수가 4개 이하인 경우 | 84 | // 제품 개수가 4개 이하인 경우 |
57 | - break; | 85 | + break searchLoop; |
58 | } | 86 | } |
59 | } | 87 | } |
60 | } | 88 | } |
61 | - | 89 | + break site; |
62 | - // 2. 펜카페 | 90 | + case 1: |
91 | + // 펜카페 | ||
63 | try { | 92 | try { |
64 | - console.log("pencafe crawling"); | 93 | + var pencafe_url = url + search + "&sort=price" |
65 | - await page .goto('http://www.pencafe.co.kr'); | 94 | + await page.goto(pencafe_url); |
66 | - | 95 | + // console.log("pencafe crawling"); |
67 | - // args[0] 검색 | 96 | + |
68 | - await page.waitForSelector('#header > div.hd_mib > div.hd_sch.f_left > form > fieldset > input'); | 97 | + // 페이지 로딩 대기 |
69 | - await page .type('#header > div.hd_mib > div.hd_sch.f_left > form > fieldset > input', args[0]); | 98 | + await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child(4) > dd > ul > li.prd-name > a'); |
70 | - await page .keyboard.press( "Enter" ); | ||
71 | - // await page.screenshot({ path : "screenshot.png" }); | ||
72 | } catch { ; } // 사이트 링크에 이상이 생겼거나 검색에 문제가 생겼을 경우 프로그램이 종료되는 것을 방지 | 99 | } catch { ; } // 사이트 링크에 이상이 생겼거나 검색에 문제가 생겼을 경우 프로그램이 종료되는 것을 방지 |
73 | 100 | ||
74 | // 검색 결과 가져오기 (최대 4개) | 101 | // 검색 결과 가져오기 (최대 4개) |
75 | - var pencafe = ''; | 102 | + searchLoop : for (var i = 1; i <= 4; i++) { |
76 | - for (var i = 1; i <= 4; i++) { | ||
77 | try { | 103 | try { |
78 | - var title = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-name > a'); | 104 | + var title = await page.$eval('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-name > a', element => { |
79 | - var pencafe_title = await page.evaluate( title => title.textContent, title ); | 105 | + return element.textContent; |
80 | - // console.log("펜카페 검색 결과 제품명 : ", pencafe_title); | 106 | + }); |
107 | + // console.log("펜카페 검색 결과 제품명 : ", title); | ||
81 | 108 | ||
82 | // 펜카페 구조상 제품명 앞에 할인률(ex. 17%)이 붙는 경우가 많음 -> 제거 | 109 | // 펜카페 구조상 제품명 앞에 할인률(ex. 17%)이 붙는 경우가 많음 -> 제거 |
83 | - if (pencafe_title.indexOf('%') != -1) { pencafe_title = pencafe_title.slice(pencafe_title.indexOf('%')+1); } | 110 | + if (title.indexOf('%') != -1) { title = title.slice(title.indexOf('%')+1); } |
84 | // 펜카페 구조상 제품명 뒤에 사족(ex. (색상선택/금장~~~))이 붙는 경우가 많음 -> 제거 | 111 | // 펜카페 구조상 제품명 뒤에 사족(ex. (색상선택/금장~~~))이 붙는 경우가 많음 -> 제거 |
85 | - if (pencafe_title.lastIndexOf(')') == pencafe_title.length-1) { pencafe_title = pencafe_title.slice(0, pencafe_title.lastIndexOf('(')); } | 112 | + if (title.lastIndexOf(')') == title.length-1) { title = title.slice(0, title.lastIndexOf('(')); } |
86 | 113 | ||
87 | - var link = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-name > a'); | 114 | + var link = await page.$eval('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-name > a', element => { |
88 | - var pencafe_link = await page.evaluate( link => link.href, link ); | 115 | + return element.href; |
89 | - // console.log("펜카페 검색 링크 : ", pencafe_link); | 116 | + }); |
117 | + // console.log("펜카페 검색 링크 : ", link); | ||
90 | 118 | ||
91 | // 링크 구조상 &search 뒷부분은 제품 링크를 띄우는데 영향을 미치지 않음 | 119 | // 링크 구조상 &search 뒷부분은 제품 링크를 띄우는데 영향을 미치지 않음 |
92 | // -> 글자수 제한(1024)도 있으므로 제거 | 120 | // -> 글자수 제한(1024)도 있으므로 제거 |
93 | - pencafe_link = pencafe_link.slice(0, pencafe_link.indexOf('&search')); | 121 | + link = link.slice(0, link.indexOf('&search')); |
94 | 122 | ||
95 | try { | 123 | try { |
96 | - var price = await page.waitForSelector('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-price > span'); | 124 | + var price = await page.$eval('#searchWrap > div > div.item-wrap > div:nth-child(2) > dl:nth-child('+i+') > dd > ul > li.prd-price > span', element => { |
97 | - var pencafe_data = await page.evaluate( price => price.textContent, price ); | 125 | + return element.textContent; |
98 | - // console.log("펜카페 검색 결과 가격 : ", pencafe_data); | 126 | + }); |
127 | + // console.log("펜카페 검색 결과 가격 : ", price); | ||
99 | } catch { | 128 | } catch { |
100 | // 품절이라서 금액정보가 없을 경우 "SOLD OUT"으로 표시 | 129 | // 품절이라서 금액정보가 없을 경우 "SOLD OUT"으로 표시 |
101 | - pencafe_data = "SOLD OUT"; | 130 | + price = "SOLD OUT"; |
102 | } | 131 | } |
103 | 132 | ||
104 | - pencafe += `[${pencafe_title}](${pencafe_link}) - ${pencafe_data}` + '\n'; | 133 | + result += `[${title}](${link}) - ${price}` + '\n'; |
105 | } catch { | 134 | } catch { |
106 | if (i == 1) { | 135 | if (i == 1) { |
107 | // 제품 정보가 아예 없을 경우 "검색결과 없음"으로 표시 | 136 | // 제품 정보가 아예 없을 경우 "검색결과 없음"으로 표시 |
108 | - pencafe += "검색결과 없음" + '\n'; | 137 | + result += "검색결과 없음" + '\n'; |
109 | - break; | 138 | + break searchLoop; |
110 | } else { | 139 | } else { |
111 | // 제품 개수가 4개 이하인 경우 | 140 | // 제품 개수가 4개 이하인 경우 |
112 | - break; | 141 | + break searchLoop; |
113 | } | 142 | } |
114 | } | 143 | } |
115 | } | 144 | } |
116 | - | 145 | + break site; |
117 | - // 3. 블루블랙 | 146 | + case 2: |
147 | + // 블루블랙 | ||
118 | try { | 148 | try { |
119 | - console.log("blueblack crawling"); | 149 | + var blueblack_url = url + search + "&order_by=priceasc" |
120 | - await page .goto('https://blueblack.co.kr'); | 150 | + await page.goto(blueblack_url); |
121 | - | 151 | + // console.log("blublack crawling"); |
122 | - // args[0] 검색 | 152 | + |
123 | - await page.waitForSelector('#keyword'); | 153 | + // 페이지 로딩 대기 |
124 | - await page .type('#keyword', args[0]); | 154 | + await page.waitForSelector('#contents > div:nth-child(4) > ul > li:nth-child(4) > div.description > p.name > a > span:nth-child(2)'); |
125 | - await page .keyboard.press( "Enter" ); | ||
126 | - // await page.screenshot({ path : "screenshot.png" }); | ||
127 | } catch { ; } // 사이트 링크에 이상이 생겼거나 검색에 문제가 생겼을 경우 프로그램이 종료되는 것을 방지 | 155 | } catch { ; } // 사이트 링크에 이상이 생겼거나 검색에 문제가 생겼을 경우 프로그램이 종료되는 것을 방지 |
128 | 156 | ||
129 | // 검색 결과 가져오기 (최대 4개) | 157 | // 검색 결과 가져오기 (최대 4개) |
130 | - var blueblack = ''; | 158 | + searchLoop : for (var i = 1; i <= 4; i++) { |
131 | - for (var i = 1; i <= 4; i++) { | ||
132 | try { | 159 | try { |
133 | - var title = await page.waitForSelector('#contents > div:nth-child(4) > ul > li:nth-child('+i+') > div.description > p.name > a > span:nth-child(2)'); | 160 | + var title = await page.$eval('#contents > div:nth-child(4) > ul > li:nth-child('+i+') > div.description > p.name > a > span:nth-child(2)', element => { |
134 | - var blueblack_title = await page.evaluate( title => title.textContent, title ); | 161 | + return element.textContent; |
135 | - // console.log("블루블랙 검색 결과 제품명 : ", blueblack_title); | 162 | + }); |
163 | + // console.log("블루블랙 검색 결과 제품명 : ", title); | ||
136 | 164 | ||
137 | - var link = await page.waitForSelector('#contents > div:nth-child(4) > ul > li:nth-child('+i+') > div.description > p.name > a'); | 165 | + var link = await page.$eval('#contents > div:nth-child(4) > ul > li:nth-child('+i+') > div.description > p.name > a', element => { |
138 | - var blueblack_link = await page.evaluate( link => link.href, link ); | 166 | + return element.href; |
139 | - // console.log("블루블랙 검색 링크 : ", blueblack_link); | 167 | + }); |
168 | + // console.log("블루블랙 검색 링크 : ", link); | ||
140 | 169 | ||
141 | // 링크 구조상 &search 뒷부분은 제품 링크를 띄우는데 영향을 미치지 않음 | 170 | // 링크 구조상 &search 뒷부분은 제품 링크를 띄우는데 영향을 미치지 않음 |
142 | // -> 글자수 제한(1024)도 있으므로 제거 | 171 | // -> 글자수 제한(1024)도 있으므로 제거 |
143 | - pencafe_link = pencafe_link.slice(0, pencafe_link.indexOf('&cate_no')); | 172 | + link = link.slice(0, link.indexOf('&cate_no')); |
144 | 173 | ||
145 | try { | 174 | try { |
146 | // 품절 아이콘이 있는지 확인 | 175 | // 품절 아이콘이 있는지 확인 |
... | @@ -148,62 +177,70 @@ exports.run = async (client, msg, args, prefix) => { | ... | @@ -148,62 +177,70 @@ exports.run = async (client, msg, args, prefix) => { |
148 | return element.getAttribute("src"); | 177 | return element.getAttribute("src"); |
149 | }); | 178 | }); |
150 | 179 | ||
151 | - blueblack_data = 'SOLD OUT'; | 180 | + var price = 'SOLD OUT'; |
152 | } catch { | 181 | } catch { |
182 | + try { | ||
153 | // 품절 아이콘이 없을 경우 | 183 | // 품절 아이콘이 없을 경우 |
154 | - var price = await page.waitForSelector('#contents > div:nth-child(4) > ul > li:nth-child('+i+') > div.description > ul > li:nth-child(3) > span:nth-child(2)'); | 184 | + var price = await page.$eval('#contents > div:nth-child(4) > ul > li:nth-child('+i+') > div.description > ul > li:nth-child(3) > span:nth-child(2)', element => { |
155 | - var blueblack_data = await page.evaluate( price => price.textContent, price ); | 185 | + return element.textContent; |
156 | - // console.log("블루블랙 검색 결과 가격 : ", blueblack_data); | 186 | + }); |
187 | + } catch { | ||
188 | + var price = '0원'; | ||
189 | + } | ||
157 | } | 190 | } |
191 | + // console.log("블루블랙 검색 결과 가격 : ", price); | ||
158 | 192 | ||
159 | - blueblack += `[${blueblack_title}](${blueblack_link}) - ${blueblack_data}` + '\n'; | 193 | + result += `[${title}](${link}) - ${price}` + '\n'; |
160 | } catch { | 194 | } catch { |
161 | if (i == 1) { | 195 | if (i == 1) { |
162 | // 제품 정보가 아예 없을 경우 "검색결과 없음"으로 표시 | 196 | // 제품 정보가 아예 없을 경우 "검색결과 없음"으로 표시 |
163 | - blueblack += "검색결과 없음" + '\n'; | 197 | + result += "검색결과 없음" + '\n'; |
164 | - break; | 198 | + break searchLoop; |
165 | } else { | 199 | } else { |
166 | // 제품 개수가 4개 이하인 경우 | 200 | // 제품 개수가 4개 이하인 경우 |
167 | - break; | 201 | + break searchLoop; |
168 | } | 202 | } |
169 | } | 203 | } |
170 | } | 204 | } |
171 | - | 205 | + break site; |
172 | - // 4. 재팬나인 | 206 | + case 3: |
207 | + // 재팬나인 | ||
173 | try { | 208 | try { |
174 | - console.log("japannine crawling"); | 209 | + await page.goto(url); |
175 | - await page .goto('http://www.japan9.co.kr'); | 210 | + // console.log("japannine crawling"); |
176 | - | 211 | + |
177 | - // args[0] 검색 | 212 | + var japannine_url = url + search + "&sort=price" |
178 | - await page.waitForSelector('body > center > table:nth-child(7) > tbody > tr > td > table:nth-child(1) > tbody > tr > td:nth-child(2) > table > tbody > tr > td:nth-child(2) > input'); | 213 | + await page.goto(japannine_url); |
179 | - await page .type('body > center > table:nth-child(7) > tbody > tr > td > table:nth-child(1) > tbody > tr > td:nth-child(2) > table > tbody > tr > td:nth-child(2) > input', args[0]); | 214 | + // console.log("japannine crawling"); |
180 | - await page .keyboard.press( "Enter" ); | 215 | + |
181 | - // await page.screenshot({ path : "screenshot.png" }); | 216 | + // 페이지 로딩 대기 |
217 | + await page.waitForSelector('#mk_search_production > tbody > tr:nth-child(17) > td:nth-child(3) > a'); | ||
182 | } catch { ; } // 사이트 링크에 이상이 생겼거나 검색에 문제가 생겼을 경우 프로그램이 종료되는 것을 방지 | 218 | } catch { ; } // 사이트 링크에 이상이 생겼거나 검색에 문제가 생겼을 경우 프로그램이 종료되는 것을 방지 |
183 | 219 | ||
184 | // 검색 결과 가져오기 (최대 4개) | 220 | // 검색 결과 가져오기 (최대 4개) |
185 | - var japannine = ''; | 221 | + searchLoop : for (var i = 1; i <= 4; i++) { |
186 | - for (var i = 1; i <= 4; i++) { | ||
187 | try { | 222 | try { |
188 | - var title = await page.waitForSelector('#mk_search_production > tbody > tr:nth-child('+(5+((i-1)*4))+') > td:nth-child(3) > a'); | 223 | + var title = await page.$eval('#mk_search_production > tbody > tr:nth-child('+(5+((i-1)*4))+') > td:nth-child(3) > a', element => { |
189 | - var japannine_title = await page.evaluate( title => title.textContent, title ); | 224 | + return element.textContent; |
190 | - // console.log("재팬나인 검색 결과 제품명 : ", japannine_title); | 225 | + }); |
226 | + // console.log("재팬나인 검색 결과 제품명 : ", title); | ||
191 | 227 | ||
192 | // 재팬나인 구조상 제품명 앞에 항상 '/n'이 붙는다 -> 제거 | 228 | // 재팬나인 구조상 제품명 앞에 항상 '/n'이 붙는다 -> 제거 |
193 | - japannine_title = japannine_title.slice(1); | 229 | + title = title.slice(1); |
194 | // 재팬나인 구조상 제품명 앞과 뒤에 [쿠폰적용 || 주문예약상품]이 붙는 경우가 많음 -> 제거 | 230 | // 재팬나인 구조상 제품명 앞과 뒤에 [쿠폰적용 || 주문예약상품]이 붙는 경우가 많음 -> 제거 |
195 | - if (japannine_title.indexOf('[') == 0) { japannine_title = japannine_title.slice(japannine_title.indexOf(']')+1); } | 231 | + if (title.indexOf('[') == 0) { title = title.slice(title.indexOf(']')+1); } |
196 | - if (japannine_title.lastIndexOf(']') == japannine_title.length-1) { japannine_title = japannine_title.slice(0, japannine_title.lastIndexOf('[')); } | 232 | + if (title.lastIndexOf(']') == title.length-1) { title = title.slice(0, title.lastIndexOf('[')); } |
197 | - if (japannine_title.indexOf('{') == 0) { japannine_title = japannine_title.slice(japannine_title.indexOf('}')+1); } | 233 | + if (title.indexOf('{') == 0) { title = title.slice(title.indexOf('}')+1); } |
198 | - if (japannine_title.lastIndexOf('}') == japannine_title.length-1) { japannine_title = japannine_title.slice(0, japannine_title.lastIndexOf('{')); } | 234 | + if (title.lastIndexOf('}') == title.length-1) { title = title.slice(0, title.lastIndexOf('{')); } |
199 | 235 | ||
200 | - var link = await page.waitForSelector('#mk_search_production > tbody > tr:nth-child('+(5+((i-1)*4))+') > td:nth-child(3) > a'); | 236 | + var link = await page.$eval('#mk_search_production > tbody > tr:nth-child('+(5+((i-1)*4))+') > td:nth-child(3) > a', element => { |
201 | - var japannine_link = await page.evaluate( link => link.href, link ); | 237 | + return element.href; |
202 | - // console.log("재팬나인 검색 링크 : ", japannine_link); | 238 | + }); |
239 | + // console.log("재팬나인 검색 링크 : ", link); | ||
203 | 240 | ||
204 | // 링크 구조상 &search 뒷부분은 제품 링크를 띄우는데 영향을 미치지 않음 | 241 | // 링크 구조상 &search 뒷부분은 제품 링크를 띄우는데 영향을 미치지 않음 |
205 | // -> 글자수 제한(1024)도 있으므로 제거 | 242 | // -> 글자수 제한(1024)도 있으므로 제거 |
206 | - japannine_link = japannine_link.slice(0, japannine_link.indexOf('&search')); | 243 | + link = link.slice(0, link.indexOf('&search')); |
207 | 244 | ||
208 | try { | 245 | try { |
209 | // 품절 아이콘이 있는지 확인 | 246 | // 품절 아이콘이 있는지 확인 |
... | @@ -211,51 +248,51 @@ exports.run = async (client, msg, args, prefix) => { | ... | @@ -211,51 +248,51 @@ exports.run = async (client, msg, args, prefix) => { |
211 | return element.getAttribute("src"); | 248 | return element.getAttribute("src"); |
212 | }); | 249 | }); |
213 | 250 | ||
214 | - if (img_src.indexOf('no_amount0') != -1) { japannine_data = 'SOLD OUT'; } | 251 | + if (img_src.indexOf('no_amount0') != -1) { var price = 'SOLD OUT'; } |
215 | } catch { | 252 | } catch { |
216 | // 품절 아이콘이 없을 경우 | 253 | // 품절 아이콘이 없을 경우 |
217 | - var price = await page.waitForSelector('#mk_search_production > tbody > tr:nth-child('+(5+((i-1)*4))+') > td.brandprice > span'); | 254 | + var price = await page.$eval('#mk_search_production > tbody > tr:nth-child('+(5+((i-1)*4))+') > td.brandprice > span', element => { |
218 | - var japannine_data = await page.evaluate( price => price.textContent, price ); | 255 | + return element.textContent; |
219 | - // console.log("재팬나인 검색 결과 가격 : ", japannine_data); | 256 | + }); |
220 | 257 | ||
221 | // 재팬나인 구조상 금액 뒤에 (옵션에 따라 변동)이 붙는 경우가 있다 -> 제거 | 258 | // 재팬나인 구조상 금액 뒤에 (옵션에 따라 변동)이 붙는 경우가 있다 -> 제거 |
222 | - if (japannine_data.indexOf('(') != -1) { japannine_data = japannine_data.slice(0, japannine_data.indexOf('원')+1); } | 259 | + if (price.indexOf('(') != -1) { price = price.slice(0, price.indexOf('원')+1); } |
223 | } | 260 | } |
261 | + // console.log("재팬나인 검색 결과 가격 : ", price); | ||
224 | 262 | ||
225 | - japannine += `[${japannine_title}](${japannine_link}) - ${japannine_data}` + '\n'; | 263 | + result += `[${title}](${link}) - ${price}` + '\n'; |
226 | } catch { | 264 | } catch { |
227 | if (i == 1) { | 265 | if (i == 1) { |
228 | // 제품 정보가 아예 없을 경우 "검색결과 없음"으로 표시 | 266 | // 제품 정보가 아예 없을 경우 "검색결과 없음"으로 표시 |
229 | - japannine += "검색결과 없음" + '\n'; | 267 | + result += "검색결과 없음" + '\n'; |
230 | - break; | 268 | + break searchLoop; |
231 | } else { | 269 | } else { |
232 | // 제품 개수가 4개 이하인 경우 | 270 | // 제품 개수가 4개 이하인 경우 |
233 | - break; | 271 | + break searchLoop; |
234 | } | 272 | } |
235 | } | 273 | } |
236 | } | 274 | } |
275 | + break site; | ||
276 | + } | ||
237 | 277 | ||
238 | - // 브라우저 닫기 | 278 | + return result; |
239 | - await browser.close(); | 279 | + }); |
240 | - console.log('Browser Closed'); | 280 | + })) |
281 | + }); | ||
241 | 282 | ||
242 | // 검색 결과 챗봇에 출력 | 283 | // 검색 결과 챗봇에 출력 |
243 | let Commands = new Discord.MessageEmbed() | 284 | let Commands = new Discord.MessageEmbed() |
244 | - .setTitle(`${args[0]}에 대한 검색 결과`) | 285 | + .setTitle(`${search}에 대한 검색 결과`) |
245 | .setColor("E5D49A") | 286 | .setColor("E5D49A") |
246 | // 베스트펜 검색 결과 (ex. 제품명(링크) - 금액) | 287 | // 베스트펜 검색 결과 (ex. 제품명(링크) - 금액) |
247 | - .addField('베스트펜', `${bestpen.slice(0, 1023)}`) | 288 | + .addField('베스트펜', `${results[0].slice(0, 1023)}`) |
248 | // 펜카페 검색 결과 | 289 | // 펜카페 검색 결과 |
249 | - .addField('펜카페', `${pencafe.slice(0, 1023)}`) | 290 | + .addField('펜카페', `${results[1].slice(0, 1023)}`) |
250 | // 블루블랙 검색 결과 | 291 | // 블루블랙 검색 결과 |
251 | - .addField('블루블랙', `${blueblack.slice(0, 1023)}`) | 292 | + .addField('블루블랙', `${results[2].slice(0, 1023)}`) |
252 | // 재팬나인 검색 결과 | 293 | // 재팬나인 검색 결과 |
253 | - .addField('재팬나인', `${japannine.slice(0, 1023)}`) | 294 | + .addField('재팬나인', `${results[3].slice(0, 1023)}`) |
254 | msg.reply({ embeds: [Commands] }); | 295 | msg.reply({ embeds: [Commands] }); |
255 | - }); | ||
256 | - | ||
257 | - // 검색 대기 시간이 길어질 수 있으므로 사용자에게 진행상황을 알려줄 필요가 있다 | ||
258 | - msg.reply("검색중 ..."); | ||
259 | } else { | 296 | } else { |
260 | msg.reply("검색어가 없습니다. 검색어를 추가해서 다시 입력해주세요."); | 297 | msg.reply("검색어가 없습니다. 검색어를 추가해서 다시 입력해주세요."); |
261 | } | 298 | } | ... | ... |
-
Please register or login to post a comment