์ ๊ฐ ์ ์ํ ๋ก์๋ด Repository๋ ๋ค์ ๋งํฌ์์ ํ์ธํ์ธ์! (ํ์ํ์ ๋ถ๋ค๋ง ํ์ธํด๋ณด์ธ์ ๐ )
2๋ฌ๋ง์ ๋์์๋ค.
๊ทธ ๊ฐ์ ์ฌ์ค ๋ณ๋ค๋ฅธ ์ผ์ ์์๋๋ฐ, ์ด๊ฒ์ ๊ฒ ์ ๊ฒฝ์ธ ์ผ๋ค์ด ์๊ธฐ๋ ๋ฐ๋์ ๋ฒจ๋ก๊ทธ ์์ฑ์ ์ํํํ๋ค. ๊ทธ๋ฆฌ๊ณ Java
๋ด์ฉ๋ ํฌ์คํ
ํ๋ฉด์ ์๋ ๋ด์ฉ๋ ๋ค์ ์ ์ ํ์์ฑ์ ์ต๊ทผ์ ๋๋ผ๊ฒ ๋์๋ค. ์ผ๋จ ์ค๋์ ์ด์ ์ ์์ฑํ Discord.js
๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ง์ง๋ง์ผ๋ก ์ฌ์ฉ๋ฒ์ ์ ๋ฆฌํ๋๋ก ํ ์์ ์ด๋ค. (์ถํ์ ๋ ํ์ํ ๋ด์ฉ์ ์์ฑํ๋๋ก ํ๊ฒ ์ต๋๋ค.)
๋ฐ๋ผ์ ์ค๋์ ๋ก์คํธ์ํฌ ์ ํฌ์ ๋ณด์ค์ ์ด์ฉํ์ฌ, ์บ๋ฆญํฐ ์ ํฌ์ ๋ณด๋ฅผ ๋์ค์ฝ๋ ์ฑํ ์ฐฝ์ ์ถ๋ ฅํด์ฃผ๋ ๊ธฐ๋ฅ์ ๊ตฌํ์ผ๋ก ์ฐ์ ๋ง๋ฌด๋ฆฌ๋ฅผ ์ง์ด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ด์ ํฌ์คํ ๊น์ง๋ ๋ง๋ฌด๋ฆฌ ๋์๋ค๋ ๊ฐ์ ํ์ ์งํ๋ฉ๋๋ค.
์ด์ ํฌ์คํ ์ ์๋ณด์ จ์ผ๋ฉด ์ฌ๊ธฐ๋ฅผ ๋๋ฌ์ ์ดํด๋ณด์๊ณ ์ค์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
์ด์ ํฌ์คํ
์์ ๋์ค์ฝ๋ ๋ด ์ค์ ์ ํ๊ณ ๋ฉ์์ง๋ฅผ ์
๋ ฅํ๋ฉด ์ฝ์์ฐฝ์ ์ฐํ๋ ๊ฒ ๊น์ง ์งํํ์๋ค. ๋์ค์ฝ๋ ๋ด์ ์ฌ์ฉํ๋ค๋ณด๋ฉด !๋ช
๋ น์ด
, #๋ช
๋ น์ด
์ ๊ฐ์ด ํน์ ํ ๋ฌธ์ ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ฐ๋ ๋ชจ์ต์ ๋ณผ ์ ์๋ค.
๊ทธ ์ด์ ๋ ํด๋น ๋ด์ด ์ฐธ์ฌํ๊ณ ์๋ ์๋ฒ์ ๋ชจ๋ ์ฑํ
์ฑ๋์ ์ฑํ
๋ฐ์ดํฐ๊ฐ ์๋ฒ๋ก ์ ์ก๋๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ผ์ ํน์ ๋ฌธ์๊ฐ ํฌํจ๋์์๊ฒฝ์ฐ ์ฌ์ฉ์๊ฐ ๋ด์๊ฒ ๋ช
๋ น์ ๋ณด๋ธ๋ค๊ณ ์๋ฌต์ ์ธ ์ฝ์์ ํ๋ ๊ฒ์ด๋ค. (์ด๋ ๊ฒ ํ์ง ์์ผ๋ฉด ์ฌ์ฉ์๊ฐ ์ํ์ง ์๋ ์ํฉ์์๋ ๋ช
๋ น์ด ์คํ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.)
๋ค์๊ณผ ๊ฐ์ด ์ฑํ ์ฑ๋์ ์ ๋ ฅํ ๋ฐ์ดํฐ๊ฐ ์ ๋ถ ์๋ฒ๋ก ๋ค์ด์ค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ฐ๋ผ์ ์ ํํ ๋ด ์ฌ์ฉ์ ์ํด์๋ ํน์ ๋ฌธ๊ตฌ์ ๋๋ฐํ ๋ช ๋ น์ด ํํ ๋ก ์ ๋ ฅํ๋๋ก ํ๋ ๊ฒ์ด ์ข๋ค.
๊ทธ๋์ ์ฐ๋ฆฌ๋ !(๋๋ํ)
๋ฅผ ์ด์ฉํด์ !<๋ช
๋ น์ด> ๋ด์ฉ
ํ์์ผ๋ก ์
๋ ฅํด๋ณด๋๋ก ํ์.
์ด์ ์ด๋ค ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ์ ๋ ๋ด์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ์ง ๊ท์จ์ ์ ํ์ผ๋ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ ์ ์๋๋ก ํด๋ณด์.
์ฐ์ ๋์ค์ฝ๋ ์ฑํ
์ฐฝ์ด ์
๋ ฅ๋ ๋ฉ์์ง๋ฅผ ๋ฐ๋ Router
๋ ๋ค์๊ณผ ๊ฐ๋ค.
client.on('message', message => {
console.log(message);
});
๋ฐ๋ผ์ ๋ฉ์์ง๋ฅผ ๋ก๊ทธ ์ฐ์ด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ฝ์์ ๋ฐ์ดํฐ๊ฐ ์ถ๋ ฅ๋๋ค.
<ref *2> Message {
channel: <ref *1> TextChannel {
type: 'text',
deleted: false,
id: '868357534543650857',
name: 'ํ
์คํธ-์ฑ๋-2',
rawPosition: 5,
parentID: '593065339835908126',
permissionOverwrites: Collection(0) [Map] {},
topic: null,
nsfw: false,
lastMessageID: '868360251148210246',
rateLimitPerUser: 0,
lastPinTimestamp: null,
----- ์๋ต ------
messages: MessageManager {
cacheType: [class LimitedCollection extends Collection],
cache: [LimitedCollection [Map]],
channel: [Circular *1]
},
_typing: Map(1) { '316391444765999105' => [Object] }
},
deleted: false,
id: '868360251148210246',
type: 'DEFAULT',
system: false,
content: '๋ฉ์์ง ํ
์คํธ ์
๋๋ค.',
author: User {
id: '316391444765999105',
system: null,
locale: null,
flags: UserFlags { bitfield: 0 },
username: '์ด์ค์',
bot: false,
discriminator: '0496',
avatar: '5eb09554c6c341adfcdbabe0ae8eb091',
lastMessageID: '868360251148210246',
lastMessageChannelID: '868357534543650857'
}
}
(๋๋ฌด ๊ธธ์ด์ ์๋ตํ์ต๋๋ค.)
๋๋ต ์ดํด๋ณด๋ฉด ์ฑ๋์ด๋ฆ(name)
, ๋ฉ์์ง ๋ด์ฉ(content)
, ๋ฉ์์ง ์์ฑ์(author.username)
๋ฑ ๋ค์ํ ๋ด์ฉ๋ค์ ์ ๋ฌํด์ค๋ค. ์ฐ๋ฆฌ๋ ์ฐ์ ๋ฉ์์ง ๋ด์ฉ (content)
์ ์ง์คํ๋๋ก ํ์.
(ํน์ ์ฑ๋์์๋ง ํด๋น ๋ด์ด ๋ฉ์์ง๋ฅผ ๋ฐ๊ณ ์ถ๋ค๋ฉด ์ฑ๋ ์ด๋ฆ์ผ๋ก ์กฐ๊ฑด์ ๊ฑธ์ด์ ๋ฉ์์ง๋ฅผ ๋ฐ๋๋ก ํ์
๋ ๋ฉ๋๋ค.)
์ฐ์ ๋ฐ์ดํฐ ํ์์ด JSON
์ด๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ ์ ๊ทผ ๋ฐฉ์์ .(dot)
์ ์ด์ฉํด์ ํ๊ณ ํ๊ณ ๋ค์ด๊ฐ๋ฉด ๋๋ค.
๊ทธ๋ผ ๋ค์ด์จ ๋ฉ์์ง์์ ์ฑํ ๋ด์ฉ๋ง ์ถ์ถํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
client.on('message', message => {
console.log(message.content);
});
๊ทธ๋ผ !์ ํฌ์ ๋ณด <๋ด์ฉ>
์ผ๋ก ์
๋ ฅํ์ ๋ ๋ด์ฉ์ ์ ํ ๋ฐ์ดํฐ๋ง ๋ฐ์ ์ ์๋๋ก ์กฐ๊ธ ๋ ์ฝ๋๋ฅผ ์งํํด๋ณด์. (!์ ํฌ์ ๋ณด
๋ ์ ๊ฐ ์์๋ก ์ ํ ๋ช
๋ น์ด๋ผ ์ํ์๋ ๋ฌธ๊ตฌ๋ก ์์ ๊ฐ๋ฅํฉ๋๋ค!!)
ํ์ฑํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์์ ์ ์๋๋ฐ ๋ค์ํ๊ฒ ์๊ฐํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
client.on('message', message => {
const content = message.content;
// substring์ ์ด์ฉํด์ ๋งจ ์์๋ฆฌ๊ฐ !์ ํฌ์ ๋ณด์ธ์ง ํ์ธ
// (๋ช
๋ น์ด๋ ํญ์ ๋งจ ์์ ์ด๋ค๋ ๊ฐ์ ์ฑ ํ์!)
console.log(content.substring(0, 5) === '!์ ํฌ์ ๋ณด'); // ๋ช
๋ น์ด ํ์ธ
console.log(content.substring(6, content.length).trim()); // <๋ด์ฉ>
// ๋ฉ์์ง ๋ด์ฉ์ค ๋๋คํ ์ด๋ ๋ถ๋ถ์ !์ ํฌ์ ๋ณด๊ฐ ๋ค์ด์๋ ๊ฒฝ์ฐ
console.log(content.includes("!์ ํฌ์ ๋ณด")); // ๋ช
๋ น์ด ํ์ธ
console.log(content.replace("!์ ํฌ์ ๋ณด", "").trim()); // <๋ด์ฉ>
// !์ ํฌ์ ๋ณด <๋ด์ฉ>์ผ๋ก ๋ช
๋ น์ด์ ๋ด์ฉ ์ฌ์ด์ ๊ณต๋ฐฑ์ ์ด์ฉํด์
// split์ ํ ํ ๊ณต๋ฐฑ์ ๊ธฐ์ค์ผ๋ก ์ ์ชฝ์ ๋ฐ์ดํฐ๊ฐ !์ ํฌ์ ๋ณด์ธ์ง ํ์ธ
// (์ฌ์ฉ์๊ฐ ๊ณต๋ฐฑ์ ์
๋ ฅํ์ง ์์ผ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์์)
console.log(content.split(" ")[0] === '!์ ํฌ์ ๋ณด'); // ๋ช
๋ น์ด ํ์ธ
console.log(content.split(" ")[1]); // ๋ด์ฉ
});
true
์ ๊ฑฐ์ข
true
์ ๊ฑฐ์ข
true
์ ๊ฑฐ์ข
์ด์ ๋๋ฅผ ์ด์ฉํด์ ๋ช ๋ น์ด๊ฐ ์ ๋ ฅ๋์๋์ง ํ์ธํ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค. (trim์ ๋ฌธ์์ ์ ์์ ๊ณต๋ฐฑ์ ์ ๊ฑฐํด์ค๋๋ค.)
์์์ ์ฑํ ๋ฉ์์ง๊ฐ ๋ค์ด์ค๋ฉด ๋ช ๋ น์ด๋ฅผ ํ์ธํ๋ ๋ฐฉ๋ฒ๊ณผ <๋ด์ฉ>์ ์ถ์ถํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์๋๋ฐ ์ด์ ๋ ๋ค์ด์จ ๋ด์ฉ์ ๊ฐ์ง๊ณ ์ง์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๋๋ก ํ ์์ ์ด๋ค.
๋ฐ์ดํฐ๋ฅผ ์กฐํํ๊ธฐ ์ํด์ axios
๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ ์์ ์ธ๋ฐ ๊ฐ๋ตํ๊ฒ ์ค๋ช
ํ์๋ฉด Node.js
์์ HTTP
์์ฒญ์ ๋ณด๋ค ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ๋ง๋ค์ด์ง Promise
๊ธฐ๋ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค. ์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ๋๋ฌ์ ํ์ธํ์ธ์.
๋ฐ๋ผ์ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ค์ด๋ฐ์ ์์ ์ธ๋ฐ ๋ค์ด ๋ฐ๋ ๋ช ๋ น์ด๋ ๋ค์๊ณผ ๊ฐ๋ค.
npm install axios --save
๋ค์ด์ ๋ฐ์์ผ๋ฉด ์ฌ์ฉํ ์ ์๋๋ก ์ฝ๋์ ์ถ๊ฐํด์ฃผ์ด์ผ ํ๋๋ฐ ๋ค์๊ณผ ๊ฐ์ด ์ถ๊ฐํ ์ ์๋ค.
const axios = require('axios');
์ฌํ๊น์ง ์ ์ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
// require the discord.js module
const Discord = require('discord.js');
const axios = require('axios'); // ์ถ๊ฐ
// create a new Discord client
const client = new Discord.Client();
// when the client is ready, run this code
// this event will only trigger one time after logging in
client.once('ready', () => {
console.log('Ready !!!');
});
// login to Discord with your app's token
client.login('your-login-token');
client.on('message', message => {
const content = message.content;
// substring์ ์ด์ฉํด์ ๋งจ ์์๋ฆฌ๊ฐ !์ ํฌ์ ๋ณด์ธ์ง ํ์ธ
// (๋ช
๋ น์ด๋ ํญ์ ๋งจ ์์ ์ด๋ค๋ ๊ฐ์ ์ฑ ํ์!)
console.log(content.substring(0, 5) === '!์ ํฌ์ ๋ณด');
console.log(content.substring(6, content.length).trim());
// ๋ฉ์์ง ๋ด์ฉ์ค ๋๋คํ ์ด๋ ๋ถ๋ถ์ !์ ํฌ์ ๋ณด๊ฐ ๋ค์ด์๋ ๊ฒฝ์ฐ
console.log(content.includes("!์ ํฌ์ ๋ณด"));
console.log(content.replace("!์ ํฌ์ ๋ณด", "").trim());
// !์ ํฌ์ ๋ณด <๋ด์ฉ>์ผ๋ก ๋ช
๋ น์ด์ ๋ด์ฉ ์ฌ์ด์ ๊ณต๋ฐฑ์ ์ด์ฉํด์ split(์ชผ๊ฐ๋ค) ํ ํ
// ๊ณต๋ฐฑ์ ๊ธฐ์ค์ผ๋ก ์ ์ชฝ์ ๋ฐ์ดํฐ๊ฐ !์ ํฌ์ ๋ณด์ธ์ง ํ์ธ
// (์ฌ์ฉ์๊ฐ ๊ณต๋ฐฑ์ ์
๋ ฅํ์ง ์์ผ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์์)
console.log(content.split(" ")[0] === '!์ ํฌ์ ๋ณด');
console.log(content.split(" ")[1]);
});
๋ฐ๋ผ์ axios
๋ฅผ ์ด์ฉํด์ HTTP
์์ฒญ์ ๋ณด๋ด๋ณด๋๋ก ํ์. ๊ทธ ์ ์ ๋ก์คํธ์ํฌ ์ ํฌ์ ๋ณด์ค URL
์ ํ์ธํด์ผ ๋๋๋ฐ ์ ๊ฐ ์์์จ ๊ฒฐ๊ณผ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
https://lostark.game.onstove.com/Profile/Character
๊ทธ๋ฆฌ๊ณ ๊ฒ์์ ํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด URL
์ด ๋ณ๊ฒฝ๋๋ค.
https://lostark.game.onstove.com/Profile/Character/์ ๊ฑฐ์ข
๋ฐ๋ผ์ ์ฌ๊ธฐ์ ์ป์ ์ ์๋ ํํธ๋ Character/
๋ค์์ ๋๋ค์์ ์ ์ด์ฃผ๋ฉด ์ ํฌ์ ๋ณด๊ฐ ๊ฒ์๋๋ค๋ ๊ฒ์ ์ป์ ์ ์๋ค.
ํด๋น ๋ถ๋ถ์ ์ฝ๋๋ก ์ ์ด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
client.on('message', async(message) => {
const content = message.content;
const contentArr = content.split(" ");
const command = contentArr[0];
const nickname = contentArr[1];
if(command === '!์ ํฌ์ ๋ณด'){
const encodeNickName = encodeURI(nickname);
const html = await axios.get(`https://lostark.game.onstove.com/Profile/Character/${encodeNickName}`);
console.log(html);
}
});
์ค๋ช ํ๊ธฐ์ ์์
axios
๋Promise
๊ธฐ๋ฐ์ ๋น๋๊ธฐ ํต์ ์ ํ๊ธฐ ๋๋ฌธ์ ์ฝ๋๊ฐ ๋๋ ๋ ๊น์ง ๋๊ธฐํ์ง ์์ต๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์async
์await
๋ฅผ ์ด์ฉํด์ ๋๊ธฐ ๋ฐฉ์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ํด๋ฆญ!
์ฐ์ ์ฑํ ๋ฉ์์ง๋ฅผ ๊ณต๋ฐฑ์ ๊ธฐ์ค์ผ๋ก ๋๋๋ค.
๋งจ ์์๋ ๋ช ๋ น์ด, ๊ทธ ๋ค์์ ๋ด์ฉ์ด๋ผ๊ณ ๊ฐ์ ํ๋ค.
command๊ฐ !์ ํฌ์ ๋ณด
์ผ ๊ฒฝ์ฐ ๋ค์์ ์คํ
nickname ์ ๋ณด๊ฐ ํ๊ธ์ผ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ ์๋ฌ๊ฐ ๋ฌ๋ค.
UnhandledPromiseRejectionWarning: TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters
encodeURI
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํด์ ํ๊ธ์ UTF-8
๋ก ์ธ์ฝ๋ฉํด์ ์ ๋ฌํด์ค ์ ์๋๋ก ํ๋ค. (์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ ์ฐธ๊ณ )axios
์์ get
๋ฐฉ์์ ์ด์ฉํด์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์จ๋ค.
๋ก์คํธ์ํฌ ์ ํฌ์ ๋ณด์ค html
ํ๊ทธ ์ ์ฒด๊ฐ ์ฝ์์ฐฝ์ ์ฐํ๊ฒ ๋๋ค.
๋์ถฉ ์ด๋ฐ์์ผ๋ก ์ฐํ๊ฒ ๋๋ค.
๋ฐ๋ผ์ html
๋ก ๋ค์ด์จ ๋ฐ์ดํฐ ์ค์์ ์ฐ๋ฆฌ์๊ฒ ํ์ํ ์ ๋ณด๋ง์ ํ์ฑํด๋ณด๋๋ก ํ์.
๋คํ์ด๋ ์์ฃผ ๊ณ ๋ง๊ฒ html
๋ฐ์ดํฐ๋ฅผ ํ์ฑํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์กด์ฌํ๋ค.
์ฐ๋ฆฌ๋ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ ์์ ์ธ๋ฐ ๋ค์ด๋ก๋๋ ๋ค์ ๋ช
๋ น์ด๋ก ํ ์ ์๋ค.
npm install cheerio --save
Cheerio
๊ฐ html
๋ง ํ์ฑํ ์ ์๋ ๊ฒ์ด ์๋๋ผ Markup
ํํ์ ๋ฐ์ดํฐ๋ฅผ ํ์ฑํ ์ ์๋๋ก ๋์์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค. ๊ทธ๋ฐ๋ฐ Markup
์ธ์ด์ค์์ ๋จ์ฐ ์ ์ผ ์ ๋ช
ํ ์ธ์ด๊ฐ html
์ด์ด์ html
ํ์ฑ์ ๋ง์ด ์ฌ์ฉ๋๊ณ ์๋ค๊ณ ์๊ฐํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
๋ํ Cheerio
์ ์ค๋ช
์ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ ํ์๋ค.
Cheerio's selector implementation is nearly identical to jQuery's, so the API is very similar.
Cheerio
์ ์
๋ ํฐ ๊ตฌํ์ด JQuery
์ ์ ์ฌํ๋ค๊ณ ๋์์๋ค. ๋ฐ๋ผ์ JQuery
์์ ์ฌ์ฉํ๋ ๋ฌธ๋ฒ๋ค๋ก ํธํ๊ฒ ์ฌ์ฉํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ๋ $
๋ก ๋ฐ๋ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ ์ด์ ์์ ์ธ ๊ฒ ๊ฐ๋ค.
์ข ๋ ์์ธํ ๋ด์ฉ์ ๋ณด๊ณ ์ถ์ผ์๋ฉด ์ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ์๋ฉด ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๊ฐ์คํ๊ณ , ๋ณธ๊ฒฉ์ ์ผ๋ก ํ์ฑ์ ์์ํด๋ณด๋ฉด axios
๋ก ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ณ์์ ์ ์ฅํ๊ณ Cheerio
์ ์ ๋ฌํด์ฃผ๋๋ก ํ์.
client.on('message', async(message) => {
const content = message.content;
const contentArr = content.split(" ");
const command = contentArr[0];
const nickname = contentArr[1];
if(command === '!์ ํฌ์ ๋ณด'){
const encodeNickName = encodeURI(nickname);
const html = await axios.get(`https://lostark.game.onstove.com/Profile/Character/${encodeNickName}`);
const $ = cheerio.load(html.data);
}
});
axios
๋ก ํธ์ถํ ๋ฆฌํด๊ฐ์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐ์ดํฐ๋ data
๋ผ๋ ํค ๋ฐ์ ๋ค์ด์๋ค. (https://jsonplaceholder.typicode.com/users ํ
์คํธ ์์ฒญํ ๊ฒฐ๊ณผ๊ฐ)
{
status: 200,
statusText: 'OK',
----- ์๋ต ------
},
data: [
{
id: 1,
name: 'Leanne Graham',
username: 'Bret',
email: 'Sincere@april.biz',
address: [Object],
phone: '1-770-736-8031 x56442',
website: 'hildegard.org',
company: [Object]
},
{
id: 2,
name: 'Ervin Howell',
username: 'Antonette',
email: 'Shanna@melissa.tv',
address: [Object],
phone: '010-692-6593 x09125',
website: 'anastasia.net',
company: [Object]
}
]
}
๋ฐ๋ผ์ cheerio
์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด์ค๋ html.data
๋ก ์ ๋ฌํด์ฃผ๋ฉด ๋๋ค.
(html.data
์ ์ ํฌ์ ๋ณด์ค html
์ ๋ณด๊ฐ ๋ค์ด์์ ๊ฒ์ด๋ค.)
์ด์ ๋ถํฐ ์ง์ง ์ง์ง๋ก ๋ฐ์ดํฐ๋ฅผ ํ์ฑํด์ผ๋๋๋ฐ ๋จผ์ element
์ ๊ตฌ์กฐ๋ฅผ ์ดํด๋ณด์์ผ ํ๋ค.
๋๋ค์์ ๊ฒฝ์ฐ span
ํ๊ทธ์ธ๋ฐ className
์ด profile-character-info__name
์ธ ๊ณณ์ ๋ค์ด์๋ค. ์ ์์์ผํ๋? Cheerio
์์ ํด๋น ๊ฒฝ๋ก๋ก ์ฐพ์์ ๋ค์ด๊ฐ์ผ์ง ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์๋ค. ๋ฐ๋ก ์ฝ๋๋ก ์ค๋ช
ํ๋๋ก ํ๊ฒ ๋ค.
const encodeNickName = encodeURI(nickName);
const html = await axios.get(`https://lostark.game.onstove.com/Profile/Character/${encodeNickName}`);
const $ = cheerio.load(html.data);
const userName = $("span.profile-character-info__name").text();
console.log(`๋ก์คํธ์ํฌ ์ ํฌ์ ๋ณด์ค์์ ๊ฐ์ ธ์จ ๋๋ค์ ์ด๋ฆ์ <${userName}> ์
๋๋ค.`);
์ถ๋ ฅ๋ด์ฉ : ๋ก์คํธ์ํฌ ์ ํฌ์ ๋ณด์ค์์ ๊ฐ์ ธ์จ ๋๋ค์ ์ด๋ฆ์ <์ ๊ฑฐ์ข> ์
๋๋ค.
cheerio.load(html.data)
: cheerio
์ html
๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๋ค.$("span.profile-character-info__name").text();
: className
์ด profile-character-info__name
์ธ ํ๊ทธ์ innerText
๋ฅผ ๊ฐ์ ธ์จ๋ค.๊ทธ๋์ ๋ฐ์ดํฐ๊ฐ ์ด๋ค ํ๊ทธ์ ์ ์ฅ๋์ด์๋์ง ์ ๋๋ ํ์ธ์ ์์ ํด์ผ์ง๋ง ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค.
์์์ text()
๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ์๋๋ฐ ํ๊ทธ๋ฅผ ์ดํด๋ณด๋ฉด title
์์ฑ์๋ ๋๋ค์ ์ ๋ณด๊ฐ ์ ์ฅ๋์ด์๋๋ฐ ์์ฑ ๊ฐ์ ์ถ์ถํ ๋๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
const userName = $("span.profile-character-info__name").attr("title");
์ด์ธ์๋ ๊ฐ๋จํ๊ฒ ์ง์ , ๋ ๋ฒจ๋ค์ ๊ฐ์ ธ์ค๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
const level = $("span.profile-character-info__lv").text();
const job = $("img.profile-character-info__img").attr("alt");
๋ณธ์ธ์ ์ฝ๋๋ ์ฐธ๊ณ ์ฉ์ด์ง ์ ๋ต์ ์๋๋๋ค! ๋ ์ข์ ์ฝ๋๊ฐ ์์ ์ ์์ต๋๋ค!
๋ง์ง๋ง์ด๋ค.
์ด์ ๊ฐ์ ธ์จ ๋ฐ์ดํฐ๋ฅผ ๋์ค์ฝ๋ ์ฑ๋์ ์ ์กํ๋ ๋ถ๋ถ์ ์์๋ณด๋๋ก ํ์.
์ผ๋จ ์ฑ๋๋ก ๋ค์ ๋ฉ์์ง๋ฅผ ์ ์กํ๋ ๋ถ๋ถ์ ๊ต์ฅํ ์ฝ๋ค. ์ฝ๋๋ก ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค. (๊ณต์๋ฌธ์ ์ฐธ๊ณ ๋ ์ฌ๊ธฐ์ ํ์๋ฉด ๋ฉ๋๋ค.)
const $ = cheerio.load(html.data);
const userName = $("span.profile-character-info__name").attr("title");
const level = $("span.profile-character-info__lv").text();
const job = $("img.profile-character-info__img").attr("alt");
await message.channel.send(`${userName}์ ๋ ๋ฒจ์ ${level}์ด๊ณ ์ง์
์ ${job}์
๋๋ค.`);
๊ทธ๋ฌ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ถ๋ ฅ๋ฉ๋๋ค.
๋ง์ง๋ง ์ค์ ์๋ฏธ๊ฐ message
๊ฐ์ฒด์ ์ ์ฅ๋ channel
๋ก ๋ฉ์์ง๋ฅผ ์ ์กํ๋ค๊ณ ์๊ฐํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
ํ์ง๋ง ์ด๋ ๊ฒ ๋ณด๋ด๋ฉด ๋ฐ๋ฐํด์ ์ฌ๋ฏธ๊ฐ ์๋ค. ๋ฐ๋ผ์ MessageEmbed
๋ฅผ ์ด์ฉํด์ ์ข ๋ ๋ค์ฑ๋กญ๊ฒ ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ์ ์๋๋ฐ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
์ค๋๋ง์ ๋ฒจ๋ก๊ทธ ํฌ์คํ ์ ํ๋๋ฐ ์๊ฐ์ด ๊ฝค๋ ๊ฑธ๋ ธ๋ค. ํ์ง๋ง ์ด๊ฑฐ๋งํผ ์ข์ ํฌ์คํด๋ฆฌ์ค๋ ์๋ค๊ณ ์๊ฐํ๋ค. ์์ผ๋ก๋ ์ง์ง ์ง์ง๋ก ๊พธ์คํ ํฌ์คํ ํด์ ๊ฒ์๊ธ ๊ฐ์์ข ๋๋ฆฌ๊ณ ์กฐํ์๊ฐ ๋์ ๋ฒจ๋ก๊ทธ๋ก ๋ฐ๋์ ํ๊ณ ์ถ๋ค.
๊ทธ๋ผ ์ค๋์ ์ด๋ ๊ฒ ๋ง๋ฌด๋ฆฌํ๊ฒ ์ต๋๋ค.
๊ธด ๊ธ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
ใ ใ ใ ์คํ๋ฅผ ์ฐพ์๋ฒ๋ ธ๋ค..ใ ใ