분석하고싶은코코

던전앤파이터 상급던전 입장권 분석(1) 본문

데이터분석

던전앤파이터 상급던전 입장권 분석(1)

코코로코코 2023. 4. 17. 15:16
반응형

드디어 던전앤파이터 아이템 분석을 프로젝트를 끝냈다. 포스팅한지 좀 오래걸리긴 했는데 그만큼 데이터를 쌓아야 분석이 가능한 주제라 시간이 좀 오래걸렸다ㅠ...

 

https://coco0414.tistory.com/38

 

던전앤파이터 데이터 분석

다양한 API를 활용해서 여러가지 분석을 해보려고 노력중이다. 이번 프로젝트는 던전앤파이터 API를 활용해서 게임 데이터로 분석을 진행해보려고한다. 이번 프로젝트의 대상 아이템은 상급던전

coco0414.tistory.com

 

 

그런디... 지난번에 포스팅한 후에 코드를 다시 보니 중복된 데이터가 계속 DB에 들어가고 있는게 보여서 이부분을 수정하고, 새로운 데이터에 대한 검사 부분도 조금  수정해서 이부분부터 다시 포스팅 하려고합니다.

 

 

이번 프로젝트는 VSCode에서 작업했습니다.

 

 

던전앤파이터 API - AWS DB


기본 정보

import requests
import pandas as pd
import time

import warnings
warnings.filterwarnings('ignore')


api_key = '던전앤파이터 API-key'

api_key는 발급받은 본인 api-key를 입력하면 됩니다.

 

 

API 사용 함수

# 아이템 정보 가져오기 API
def df_search_item(itemName = '', item_hashtag = ''):
    url = 'https://api.neople.co.kr/df/items'

    params = {
        'limit' : 30,
        'apikey' : api_key,
        'wordType' : 'match'
    }

    if itemName != '':
        params['itemName'] = itemName
    if item_hashtag != '':
        params['hashtag'] = item_hashtag

    return requests.get(url, params=params)

# 아이템 세부정보 가져오기 API
def df_get_item_details(itemId):
    url = f'https://api.neople.co.kr/df/items/{itemId}?apikey={api_key}'
    return requests.get(url)
    
# 경매장 등록 아이템 정보 가져오기 API
def df_aution_item(itemName, limit=100):
    url = f'https://api.neople.co.kr/df/auction'
    params = {
        'itemName' : itemName,
        'limit' : limit,
        'sort' : 'auctionNo:desc',
        'apikey' : api_key
        
    }
    
    return requests.get(url, params=params)


# 경매장 판매 이력 정보 가져오기 API
def df_aution_sold(itemName, limit=100):
    url = f'https://api.neople.co.kr/df/auction-sold'
    params = {
        'itemName' : itemName,
        'limit' : limit,
        'apikey' : api_key
    }
    
    return requests.get(url, params = params)

 

SQL함수

import  mysql.connector

# DB 연결 함수
def init_mysql():
    aws = mysql.connector.Connect(
        database = 'df',
        host = "DB host 정보 입력",
        port = 3306,
        user = 'sold_table',
        password = '1234'
    )
    return aws
    
# DB에서 데이터 가져오기
def get_data_from_db(check_type, target = ''):
    aws = init_mysql()
    cur = aws.cursor()
    
    if check_type == 'regi':
        query = 'SELECT auctionNo FROM ticket_history'
        cur.execute(query)
        result = pd.DataFrame(cur.fetchall(), columns={'auctionNo'})['auctionNo'].values
        aws.close()
        return result
    
    elif check_type == 'sold':
        query = f"Select soldDate from sold_history where itemName like '%{target}%'"
        cur.execute(query)
        result = pd.DataFrame(cur.fetchall(), columns={'soldDate'})['soldDate'].values
        aws.close()
        return result
        
        
# DB에 데이터 삽입
def excecuteDB(df, check_type):
    aws = init_mysql()
    cur = aws.cursor()
    cols = df.columns
    insert_cols = ",".join(cols)
    
    for idx, row in df.iterrows():
        insert_value = ['"'+str(row[col])+'"' for col in cols]
        insert_value = ",".join(map(str,insert_value))
        
        query = ''
        
        if check_type == 'regi':
            query = 'INSERT INTO ticket_history('+ insert_cols +') VALUES('+ insert_value +');'
            
        elif check_type == 'sold':
            query = 'INSERT INTO sold_history('+ insert_cols +') VALUES('+ insert_value +');'
        
        if query != '':
            cur.execute(query)
        
    aws.commit()
    aws.close()
    
    
# 티켓 이름 만들기 - API를 통해서 정보 가져오기
def make_ticket_names():
    high_dungeon = ['마이스터의 실험실', '파괴된 죽은 자의 성', '노블레스 코드', '노블레스 코드 : 더스크']
    grades = ['(노멀)' , '(익스퍼트)', '(마스터)']

    ticket_naems = [dungeon + " " + grade + ' 입장권' for grade in grades for dungeon in high_dungeon]
    ticket_naems

    item_dicts = dict()

    for name in ticket_naems:
        items = df_search_item(itemName=name).json()['rows']
        
        # 입장권의 획득 방식으로 동명인 아이템이 존재하기 때문에 구분짓기 위해 이름 뒤에 숫자를 붙임
        for idx, item in enumerate(items):
            item_dicts[item['itemName']+str(idx)] = item['itemId']

    return item_dicts


# 획득처 중 경매장을 통해서만 획득 가능한 아이템 정보 가져오기
def duplicated_dicts():
    item_dicts = make_ticket_names()
    result = dict()
    for key,item_id in item_dicts.items():
        if '경매장' in df_get_item_details(item_id).json()['itemObtainInfo']:

            result[key[:-1]] = item_id #itemName 맨뒤 숫자 제거
    
    return result
    
# 경매장에서 거래 가능한 아이템 정보 가져오기
item_dicts = duplicated_dicts()

연결 - 데이터 입력 - 데이터 가져오기 함수입니다.

 

입장권에 대한 아이템은 교환 불가, 교환 가능 형태 두 가지가 있습니다. 제가 필요한 정보는 교환 가능한 아이템이기 때문에 '경매장'이라는 키워드를 통해서 교환 가능 아이템에 대한 정보만 가져오도록 함수를 만들었습니다.

 

 

메인

# 경매장 데이터 탐색
# 등록과 판매 체크리스트가 따로 존재.
# 판매의 경우 아이템별로 판매일시 정보가 들어가 있음.

new_check_regi_lst = []
new_check_sold_lst = {search_id : [] for search_id in item_dicts.keys()}
search_type = ['regi', 'sold']
isFrist = True

while True:
    for target in item_dicts.keys():
        try:
            for check_type in search_type:
                search_and_regi_item(target, new_check_regi_lst, new_check_sold_lst, isFrist, check_type = check_type)
        except Exception as e:
            print(f"{target} Error -> ", e)
            time.sleep(1)
            
    isFrist = False
    time.sleep(0.5)

search_and_regi_item함수를 호출하면 새로운 아이템 탐색하고 새로운 아이템이라면 DB에 등록하는 작업까지 진행하게 됩니다.

 

[매개변수]

target -> 탐색 아이템 이름

new_check_regi_lst -> 탐색한 아이템에 대한  정보를 가지고 있습니다. 새로운 아이템인지 판별할때 사용합니다.

new_check_sold_lst -> 등록 리스트와 같이 판매된 아이템인지 판단할때 사용합니다. 다만 다른점은  리스트가 아닌 딕셔너리 형태로 아이템의 고유 아이디를 키값으로 갖고 그 안에 거래된 시간 정보가 들어있어 이를 바탕으로 새로운 아이템인지 판단합니다.

 

isFirst -> 처음 실행하는지 판단하는 매개변수입니다. 이 파일을 24시간 실행시키고 있을  수 없어서 추가한 부분입니다. 참 값일 경우 DB에서 데이터를 가져오는 작업을 진행하고 이후 참 값이 아니기 때문에 DB에서 데이터를 가져오지 않습니다.

 

check_type =  등록, 판매에 대한 정보를 전달합니다. 해당 정보에 맞게 DB 테이블에 접근합니다.

 

 

 

 

반응형