데이터분석/미니프로젝트 05. Naver API 활용

05-02. Naver API에서 모은 원피스 데이터 정리하고 시각화하기

책다니엘 2024. 4. 21. 05:10

1. 이번에는 봄을 맞아 '원피스'이라는 키워드를 검색해보고 데이터화, 시각화할 것이다. 먼저 앞서 불러온 네이버 API를 이용해 '원피스' 키워드를 검색해보자. 쇼핑 결과를 볼 것이다.

 

2. 함수는 아래와 같은 방식으로 만들어질 것이다.

  1. '검색 url'을 만드는 함수
  2. 검색 결과를 저장하는 함수
  3. DataFrame으로 저장하는 함수
  4. 앞서 만든 함수들을 실행하며 데이터를 수집하는 함수
  5. 최종적으로 엑셀로 저장하는 함수

실제 SW개발은 절차를 명시한 뒤, 함수의 입출력/인아웃을 명시하고 역할을 분담하여 진행하는 경우가 많다. 이번에는 가볍게 흉내만 내는 정도로 보면 될 것이다.

출처: 제로베이스

2-1. gen_search_url

먼저 검색해야 할 url을 만들어야 한다. 네이버 개발 가이드의 '요청 변수' 항목을 보면 검색 url의 쿼리에 들어갈 부분에는 많은 변수들이 있다. 해당 옵션을 사용해서 url을 만들어야 한다.

# 패러미터는 아래와 같은 형식으로 쿼리로 전달한다
url = "https://openapi.naver.com/v1/search/shop?query=" + encText + "&start=20&display=100" # JSON 결과

 

먼저 함수를 만들어보자.

def gen_search_url(api_node, search_text, start_num, disp_num):
    base = 'https://openapi.naver.com/v1/search'
    node = '/' + api_node + '.json'
    param_query = '?query=' + urllib.parse.quote(search_text)
    param_start = '&start=' + str(start_num)
    param_disp = '&display=' + str(disp_num)

    return base+node+param_query+param_start+param_disp

url을 잘 생성해낸다.

 

2-2. get_result_onpage()

2-1에서 만든 url을 이 함수에 던져 준다. 

import json
import datetime
def get_result_onpage():
    request = urllib.request.Request(url)
    request.add_header("X-Naver-Client-Id",client_id)
    request.add_header("X-Naver-Client-Secret",client_secret)
    response = urllib.request.urlopen(request)
    print("[%s] Url Request Success" % datetime.datetime.now())
    return json.loads(response.read().decode('utf-8'))

검색이 잘 된다.

 

 

2-3. get_fields():

2-2에서 받아 온 결과들의 'items'에서 필요한 정보들을 받아 온다.

검색어를 '원피스'로 변경하였다.

이렇게 받아온 정보들을 pandas의 dataframe화해야 한다. 우선 json데이터를 받아와 pandas의 데이터프레임에 추가하는 함수를 만든다.

import pandas as pd

def get_fields(json_data):
    title = [each['title'] for each in json_data['items']]
    link = [each['link'] for each in json_data['items']]
    lprice = [each['lprice'] for each in json_data['items']]
    mall_name = [each['mallName'] for each in json_data['items']]

    result_pd = pd.DataFrame({
        'title':title,
        'link':link,
        'lprice':lprice,
        'mall':mall_name,
    }, columns=['title', 'link', 'lprice', 'mall'])

    return result_pd

 

그리고 위 함수에 2-2에서 받아온 json_data를 넣어 준다.

원 결괏값에 계속 <b>태그가 나와 간단한 함수를 만들어 지워주었다.

지금까지 만든 함수들을 변수로 정리하면 다음과 같이 된다. 이제 반복문을 돌려 주면 된다.

url = gen_search_url('shop', '원피스', 1, 5)
json_result = get_result_onpage(url)
pd_result = get_fields(json_result)

 

2-4. actMain():

 

반복문을 돌려서 result_mol이라는 리스트형 안에 담기는 데이터는 pandas dataframe데이터이다. 이걸 pd.concat() 기능을 통해 이어붙일 수 있다.

result_mol = []

for n in range(1, 1000, 100):
    url = gen_search_url('shop', '원피스', n, 100)
    json_result = get_result_onpage(url)
    pd_result = get_fields(json_result)

    result_mol.append(pd_result)
result_mol = pd.concat(result_mol)
result_mol

멋지게 1000개의 데이터가 들어갔다.
info()로 확인해도 이상이 없다

가격을 숫자형으로 바꿔주고, 이제 이 반복문을 함수로 만들어주자.

def actMain(search_value):
    result_mol = []

    for n in range(1, 1000, 100):
        url = gen_search_url('shop', search_value, n, 100)
        json_result = get_result_onpage(url)
        pd_result = get_fields(json_result)

        result_mol.append(pd_result)
    result_mol = pd.concat(result_mol)
    result_mol['lprice'] = result_mol['lprice'].astype('float')
    return result_mol

 

잘 된다!

 

2-5. toExcel():

이제 위에서 받아온 데이터들을 엑셀에 저장해야 한다. 코드는 다음과 같다.

writer = pd.ExcelWriter('../data/06_onepiece_in_naver_shop.xlsx', engine='xlsxwriter')
result_mol.to_excel(writer, sheet_name = 'Sheet1')

workbook = writer.book
worksheet = writer.sheets['Sheet1']
worksheet.set_column('A:A', 4)
worksheet.set_column('B:B', 60)
worksheet.set_column('C:C', 10)
worksheet.set_column('D:D', 10)
worksheet.set_column('E:E', 50)
worksheet.set_column('F:F', 10)

worksheet.conditional_format('C2:C1001', {'type':'3_color_scale'})
writer.close()

완전히 처음 보는 코드들ㅠㅠ

 

일단 xlsxwriter을 pip install해준다.

pip install xlsxwriter

 

** xlsxwriter에는 방대한 기능이 있다. 엑셀에 그래프를 넣을 수도 있고, 가운데 정렬, 수식 등등 모든 기능을 활용할 수 있다. 차후 API나 크롤링으로 얻어온 데이터를 활용하기 위해 반드시 익혀야겠지만, 일단 여기서는 특정 기능만 사용한다.

 

위의 코드를 실행해보자. 잘 저장되나 확인해본다.

잘 된다! 심지어 멋지다!

그러면 이상의 코드를 함수화하자.

def toExcel(pd_data, excel_title):
    writer = pd.ExcelWriter(f'../data/{excel_title}', engine='xlsxwriter')
    pd_data.to_excel(writer, sheet_name = 'Sheet1')

    workbook = writer.book
    worksheet = writer.sheets['Sheet1']
    worksheet.set_column('A:A', 4) # A컬럼 4칸
    worksheet.set_column('B:B', 60) # B컬럼 60칸
    worksheet.set_column('C:C', 10) # ...
    worksheet.set_column('D:D', 10)
    worksheet.set_column('E:E', 50)
    worksheet.set_column('F:F', 10)

    worksheet.conditional_format('C2:C1001', {'type':'3_color_scale'}) # 3_color_scale이라는 액셀함수를 적용함
    writer.close()

 

최종적으로 함수를 실행하면 다음과 같다.

toExcel(actMain('원피스'), '06_onpiece_in_naver_shop_02.xlsx')

잘 저장되는 것까지 확인했다.


 

3. 이제 시각화를 해보자. matplotlib 한글 세팅을 하고 저장한 엑셀 파일을 불러와 다뤄 보자.

import set_matplotlib_hangul

** 이전에 작성한 matplotlib 한글 세팅 모듈을 그대로 불러왔다.

plt.figure(figsize=(15,6))
sns.countplot(
    x=result_mol['mall'],
    data=result_mol,
    palette='RdYlGn',
    order=result_mol['mall'].value_counts().index
)
plt.xticks(rotation=90)
plt.show()

seaborn의 countplot기능을 사용한다. x축에 result_mol['mall']로 판매점 이름을, data는 result_mol을, 팔레트는 'RdYlGn'을, 데이터의 배치 순서를 result_mol['mall']의 값을 카운트한 결과로 했다. plt.xticks(rotation=90)으로 x축의 값들(가게 이름)을 90도 회전시켜 보기 편하게 했다. 결과는 다음과 같다.

거의 대부분의 옷들을 '네이버'에서 판다.

모든 함수를 만들고 시각화까지 했으니, 다른 것 하나만 더 만들어보자. 코로나 팬데믹 이후로 키덜트를 대표하는 아이템 중 하나가 된 '건담' 키워드를 한 번 검색해볼 것이다.

toExcel(actMain('건담'), '06_gundam_in_naver_shop.xlsx')
df = pd.read_excel('../data/06_gundam_in_naver_shop.xlsx', thousands=',')
del df['Unnamed: 0'] ## 불필요한 컬럼 제거

plt.figure(figsize=(15,6))
sns.countplot(
    x=df['mall'],
    data=df,
    palette='RdYlGn',
    order=df['mall'].value_counts().index
)

plt.xticks(rotation=90)
plt.show()

프로젝트가 잘 마무리되었다.