흥겜 로스트아크를 친구들과 즐기는 와중, 최근 하이퍼 익스프레스와 점핑권 지급으로 부캐들이 늘어나면서 레이드 스케줄을 짜는 것에 어려움이 있었습니다.
주간 컨텐츠인 레이드를 누가 갔는지 안갔는지, 누가 갈 수 있고 못가는지 등등 이런 스케줄 문제들을 일일이 물어보면서 결정하는 것에 매우 스트레스를 받아 코딩 실력도 길러볼 겸 프로젝트를 계획하게 되었습니다.
디스코드 봇을 만들어서 스케줄 관리와 계정 정보를 쉽게 받아보고자 하였습니다.
먼저 디스코드 봇을 만드는 것은 검색을 통해 쉽게 따라할 수 있으므로 넘어가겠습니다.
가장 먼저 계정정보를 크롤링해오는 함수부터 정리하였습니다.
def crawl(Id):
url = "https://lostark.game.onstove.com/Profile/Character/" + parse.quote(Id)
html = urlopen(url)
bsObject = BeautifulSoup(html, "html.parser")
list_char = []
tmp = bsObject.select_one('div.profile-character-list').select('ul>li>span>button>span')
for n in tmp:
name = n.text
url = "https://lostark.game.onstove.com/Profile/Character/" + parse.quote(name)
html = urlopen(url)
bsObject = BeautifulSoup(html, "html.parser")
serv = bsObject.find_all(attrs={"class": "profile-character-info__server"})
job = bsObject.find('img', "profile-character-info__img")
itemlv = bsObject.find_all("div", {"class": "level-info2__item"})[0].find_all("span")[1]
list_char.append([str(serv[0].get_text())[1:], name, job.attrs['alt'], float(itemlv.get_text()[3:].replace(',', ''))])
list_char = sorted(list_char, key = lambda x : -1*x[3])
return list_char
일단 request와 beautifulsoup4를 사용하였고 추후 더 많은 정보 크롤링이 필요로 한다면, 셀레니움을 사용하는 쪽으로 리펙토링할 생각입니다.
크롤링 함수는 로스트아크 캐릭터 Id를 받아서 해당 캐릭터의 원정대의 모든 캐릭터의 정보를 아이템 레벨 순으로 정렬하여 리스트로 반환합니다.
길드원들의 정보를 관리하는데 크롤링 함수가 매번 호출되는 것은 매우 비효율적입니다. 디스코드에서 서버 내 멤버들의 닉네임이 바뀌더라도 Hash를 얻어낼 수 있습니다. 간단한 DB를 구현하여 디스코드 {Discord_Hash : [원정대정보]} 데이터 형식으로 데이터를 저장하게 하고, 들고 있다가 만약 DB에 있는 데이터를 호출하면 크롤링하지 않고 바로 보여주게 하였습니다.
class DB():
def __init__(self,folder):
self.folder = folder
self.data = self.load()
def call(self,Hash,Id):
# return : {Hash : [[server,Id,직업,level],~]}
if Hash in self.data:
return self.data.get(Hash)
else:
if not Hash:
return crawl(Id)
self.data[Hash]=crawl(Id)
self.data[Id]=Hash
self.save()
return self.data.get(Hash)
길드원들의 계정연동 뿐만 아니라 단순히 계정검색을 위해서도 call 함수가 사용될 수 있습니다. Hash가 None으로 들어오고 Id값만 들어온다면 DB에 저장하지 않고 크롤링한 정보를 반환하도록 하였습니다.
다음 글에서는 이러한 함수들을 디스코드 봇 인터페이스에 사용하는 것을 보겠습니다.