본문 바로가기
공부/python

[Pytesseract를 사용한 메이플스토리 길드 스코어 분석] 메이플 랭킹 정보 수집 후 파일로 저장

by 고기 2022. 3. 30.

이전 글에서 이미지에서 문자를 인식하는 방법에 대해 알아보았다. 이번 글에서는 메이플 랭킹 정보를 수집 후 이전 글에서 저장했던 리스트와 함께 파일로 저장하는 방법에 대해 알아본다.

 

전에 작성했던 것과 마찬가지로 변환한 데이터를 파일로 저장하는 버튼을 생성하고, 메이플 랭킹 정보를 수집하기 위해 필요한 길드 마스터와 길드명을 입력할 수 있는 입력창을 생성한다.

library list
import requests
from bs4 import BeautifulSoup
from urllib.request import urlopen
import os
import pandas as pd
 
class UI:
    def __init__(self):   
        variable & window & button setting
        
        '''
        파일 저장 버튼
        '''
        self.label_save = tk.Label(self.main_window, text = "[3] 변환결과저장", font=font, bg="pink")
        self.label_save.place(x=550, y=50)
        
        self.label_guild = tk.Label(self.main_window, text = "Guild", font=font, bg="pink")
        self.label_guild.place(x=560, y=90)
        self.text_guild = tk.Entry(self.main_window, width=15, textvariable=str)
        self.text_guild.insert(0, '')
        self.text_guild.place(x=630, y=90)
        
        self.label_master = tk.Label(self.main_window, text = "Master", font=font, bg="pink")
        self.label_master.place(x=550, y=120)
        self.text_master = tk.Entry(self.main_window, width=15, textvariable=str)
        self.text_master.insert(0, '')
        self.text_master.place(x=630, y=120)
        
        btn_save = tk.Button(self.main_window, text="Save excel", font=font, bg="pink", overrelief="solid", command=self.call_save_excel, repeatdelay=1000)
        btn_save.place(x=550, y=160)             
        
    '''
    파일 저장
    '''
    def call_save_excel(self):
        self.main_window.destroy()

 

코드를 설명하기 전에 save Button의 command 함수인 save_excel() 함수의 작동과정을 간단히 설명하면 이렇다.

 

먼저 입력으로 받은 길드마스터와 길드명을 메이플스토리 공식 홈페이지 길드랭킹에서 검색해서 찾는다.

사진1

 

반복문을 돌면서 모든 길드원 이름을 저장한다.

사진2

 

길드원 이름이 저장된 리스트를 오름차순으로 정렬시킨다. 이름을 정렬시키는 이유는 메이플 내부에서 직접 데이터를 가져오는 것이 아니고 이전 글에서 작성한 것처럼 길드 컨텐츠 점수를 스크린샷으로 저장하는 방식으로 점수 데이터를 가져왔었는데, 이 때 닉네임이나 기타 정보들까지 가져오는 것이 아니라서 비교할 수 있는 컬럼이 없다. 따라서 닉네임을 정렬 시켜주지 않으면 아래 사진처럼 닉네임과 점수를 서로 매치시킬 수 없기 때문이다.

사진3

 

변환시킨 점수 데이터와 정렬시킨 닉네임 리스트를 합쳐서 파일로 저장한다.

사진4

 

다시 코드로 돌아와서, 길드 검색을 위한 함수를 작성한다. 16~19라인은 사진1처럼 입력된 길드명을 검색하는 코드다. 그 아래로 21~32라인은 사진1에서 검색된 같은 이름의 길드들 중에서 입력된 길드 마스터와 같으면 해당 길드정보 url을 저장하는 코드다.

library list
import requests
from bs4 import BeautifulSoup
from urllib.request import urlopen
import os
import pandas as pd
 
class UI:
    def __init__(self):   
        variable & window & button setting
        
    '''
    길드 검색
    '''
    def parse_maple_guild(self, guild, master):
        url = "https://maplestory.nexon.com/Ranking/World/Guild?t=1&n=" + guild
        rank_html = get_html(url)
        soup = BeautifulSoup(rank_html, 'html.parser')
        maple_rank = soup.find("table", {"class": "rank_table2"}).find_all("td", {"class": "left"})

        for index in maple_rank:
            info_soup = index.find("a")
            _url = info_soup["href"]
            _text = info_soup.text.split(".")
            _num = _text[0]

            self.master_name.append(_num)
            self.guild_url.append(_url)

        for i in range(0, int(len(self.master_name)/2)):
            if self.master_name[1+i*2] == master:
                self.guild_url.append(self.guild_url[i*2])

    '''
    파일 저장
    '''
    def call_save_excel(self):        
        guild = self.text_guild.get()
        master = self.text_master.get()           
        parse_maple_guild(guild, master)
        
        self.main_window.destroy()

 

 

parse_maple_guild() 함수에서 저장했던 길드 url으로 다시 검색한다. 1페이지부터 마지막 페이지까지 돌기 위해 n번 반복해서 캐릭터 닉네임을 가져오면 되는데, 반복하는 횟수는 이전 글에서 저장했던 길드 컨텐츠 점수의 길이를 사용한다. 점수 길이만큼 반복문을 돌면서 길드원 닉네임을 리스트에 저장하고 마지막에 리스트를 오름차순 정렬한다.

 

26~47라인에서 if ~ else를 쓴 이유는 메이플 길드 정보에서는 한 페이지에 20캐릭터가 출력되는데, 만약 점수의 길이가 20이라고 했을 때 1개의 페이지를 출력하면 되지만, 점수의 길이가 21이라고 했을 때, 2개의 페이지를 출력하게 지정해주어야 하기 때문이다.

library list
import requests
from bs4 import BeautifulSoup
from urllib.request import urlopen
import os
import pandas as pd
 
class UI:
    def __init__(self):   
        variable & window & button setting
        
    '''
    길드 검색
    '''
    def parse_maple_guild(self, guild, master):
        입력된 길드 url 찾아서 리스트에 저장

    '''
    길드원 닉네임 리스트 오름차순으로 가져옴
    '''    
    def parse_guild_list(self):        
        url = "https://maplestory.nexon.com/" + self.guild_url[len(self.guild_url)-1]
        member = len(self.save_f)
        
        if member % 20 == 0:
            for i in range(0, int(member/20)):            
                rank_html = get_html(url + "&orderby=0&page=" + str(i+1))
                soup = BeautifulSoup(rank_html, 'html.parser')        
                g_index = soup.find("table", {"class":"rank_table"}).find_all("td", {"class":"left"})

                for index in g_index:
                    info_soup = index.find("a")
                    _text = info_soup.text.split(".")
                    _name = _text[0]
                    self.guild_list.append(_name)
        else:
            for j in range(0, int(member/20)+1):                        
                rank_html = get_html(url + "&orderby=0&page=" + str(j+1))
                soup = BeautifulSoup(rank_html, 'html.parser')        
                g_index = soup.find("table", {"class":"rank_table"}).find_all("td", {"class":"left"})

                for index in g_index:
                    info_soup = index.find("a")
                    _text = info_soup.text.split(".")
                    _name = _text[0]
                    self.guild_list.append(_name)

        self.guild_list.sort()
        
    '''
    파일 저장
    '''
    def call_save_excel(self):
        guild = self.text_guild.get()
        master = self.text_master.get()           
        parse_maple_guild(guild, master)
        parse_guild_list()

 

23~39 라인은 이미지를 문자로 변환했을 때 저장된 데이터들을 처리하는 과정이다. 사실 왜 그렇게 되는지는 모르겠는데 문자로 변환할 때 0은 ''으로 저장되고, 0이 아닌 것들은 뒤에 줄바꿈(\n)이 붙어서 저장되기 때문에 이 값들을 변환시켜줬다.

library list
import requests
from bs4 import BeautifulSoup
from urllib.request import urlopen
import os
import pandas as pd
 
class UI:
    def __init__(self):   
        variable & window & button setting
                
    '''
    파일 저장
    '''
    def call_save_excel(self):
        입력된 길드 url 찾아서 리스트에 저장
        길드원 닉네임 리스트로 저장
        길드원 닉네임 리스트 오름차순 정렬
        
        '''
        ''를 0으로 변환
        '''
        for z in range(len(self.save_m)):
            if self.save_m[z] == '':
                self.save_m[z] = 0
            else:
                self.save_m[z] = self.save_m[z][:-1]

        for z in range(len(self.save_u)):        
            if self.save_u[z] == '':
                self.save_u[z] = 0
            else:
                self.save_u[z] = self.save_u[z][:-1]

        for z in range(len(self.save_f)):        
            if self.save_f[z] == '':
                self.save_f[z] = 0
            else:
                self.save_f[z] = self.save_f[z][:-1]

 

저장할 파일은 2개인데, 하나는 길드원 닉네임과 점수를 매치시킨 것을 데이터 프레임으로 변환한 것을 저장할 것이고, 다른 하나는 길드원들의 부캐를 정리할 수 있도록 닉네임들을 나열시킨 것을 저장할 것이다. 24~34라인은 이름과 점수를 기록한 것을 엑셀파일로 저장하는 과정이고 36~56라인은 닉네임 나열된 것을 엑셀 파일로 저장하는 과정이다.

library list
import requests
from bs4 import BeautifulSoup
from urllib.request import urlopen
import os
import pandas as pd
 
class UI:
    def __init__(self):   
        variable & window & button setting
                
    '''
    파일 저장
    '''
    def call_save_excel(self):
        입력된 길드 url 찾아서 리스트에 저장
        길드원 닉네임 리스트로 저장
        길드원 닉네임 리스트 오름차순 정렬        
        ''를 0으로 변환
        
        '''
        파일 저장
        '''
        make_list = pd.DataFrame(list(zip(self.guild_list, m_tmp, u_tmp, f_tmp)), columns=['이름', '주간미션', '지하수로', '플래그'])        
        new_base_dir = './'+self.date+'/'
        new_file_name = '길드원 리스트.xlsx'
        new_file_dir = os.path.join(new_base_dir, new_file_name)
        
        make_list.to_excel(new_file_dir,
                           na_rep='NaN',
                           header=True,
                           index=False,
                           startrow=0,
                           startcol=0)

        blank = pd.DataFrame(index=range(0,0), columns=['이름', ' '])

        for naming in make_list['이름']:
            blank = blank.append(pd.DataFrame([[naming,' ']], columns=['이름', '']), ignore_index=True)
            blank = blank.append(pd.DataFrame([[naming + '점수',' ']], columns=['이름', '']), ignore_index=True)

        fill = blank.T.fillna(' ')

        for count in range(0, int(len(blank)/2)):
            fill[count*2][1] = fill[count*2][0]

        new_base_dir2 = './'+self.date+'/'
        new_file_name2 = '여기에 부캐들 정렬할것.xlsx' # 여기를 파일.. 불러오는걸로 아 화장실
        new_file_dir2 = os.path.join(new_base_dir2, new_file_name2)

        fill.to_excel(new_file_dir2,
                      na_rep='NaN',
                      header=False,
                      index=False,
                      startrow=0,
                      startcol=0)

 

저장된 길드원 닉네임과 점수를 매치시킨 리스트는 다음과 같다.

사진5

 

저장된 부캐 정리 리스트는 다음과 같다.

사진6

 

여기까지 이미지를 문자로 변환한 것과 스크래핑을 통해 얻어온 데이터들을 취합해서 엑셀 파일로 저장하는 방법에 대해 알아보았다. 다음 글에서는 이렇게 저장한 엑셀 파일을 분석하는 방법에 대해 알아본다. 

 

그리고 사실 이전 글들도 마찬가지지만, 다른 글을 하나도 안 본채로 이 글만 봐서는 아마 무슨 내용인지 잘 모를 거라고 생각한다. (글을 너무 못써서) 작성된 글의 처음부터 읽어보거나 마지막 글에서 정리한 것을 보는 것을 권장한다.

댓글