- Naver API 사용하기
- Naver API에서 모은 몰스킨 데이터 정리
네이버의 검색 API를 사용하여
키워드를 네이버에 검색하여 얻어낸 결과(데이터)를 정리하고, 시각화하여 살펴보는 분석이다.
https://developers.naver.com/main/
Naver Developers에서, Application 등록 -> 사용 API를 선택하면
Client ID와 Secret 번호를 받을 수 있다.
네이버가 제공하는 검색 API 블로그 검색 구현 예제를 활용하여 가져온 파이썬 코드로 실습해보자~
https://developers.naver.com/docs/serviceapi/search/blog/blog.md#python
파이썬이라는 검색어를 넣었을 때, 블로그에서 나타나는 결과들을 출력
요청 url로 보내서 response 받아오면, 정보들이 담아져 돌아오고, read로 읽어들여 decode한다.
글자로 읽을 경우, decode utf-8로 설정 -> 우리가 읽을 수 있는 한글을 표현
client_id와 client_secret에는 내가 발급받은 코드들을 넣었다.
import os
import sys
import urllib.request
encText = urllib.parse.quote("파이썬")
url = "https://openapi.naver.com/v1/search/blog?query=" + encText # JSON 결과
# url = "https://openapi.naver.com/v1/search/blog.xml?query=" + encText # XML 결과
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)
rescode = response.getcode()
if(rescode==200):
response_body = response.read()
print(response_body.decode('utf-8'))
else:
print("Error Code:" + rescode)
이런 식으로 검색 결과들이 나온다.
블로그 말고도 네이버 책, 카페, 쇼핑, 백과사전 등에서 검색을 할 수 있다.
url에서 /search 뒤의 부분만 book, cafearticle, shop, encyc 로 바꿔주면 된다.
기본 원리는 블로그 예제와 같다.
encText = urllib.parse.quote("파이썬")
url = "https://openapi.naver.com/v1/search/book?query=" + encText
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)
rescode = response.getcode()
if(rescode==200):
response_body = response.read()
print(response_body.decode('utf-8'))
else:
print("Error Code:" + rescode)
이렇게 책 정보를 가져올 수 있다.
이제 naver api를 이용해 네이버 쇼핑에서 몰스킨을 검색하여 상품 정보들을 가져와 데이터프레임으로 만들고 시각화하는 작업을 해 볼 것이다.
함수로 만들어서 정리할 것이고,
- 요청할 url 만들기
- 하나의 페이지에서 데이터를 받아오기
- 데이터프레임으로 만들기
- 데이터에 붙은 html 태그들을 제거하기
- 데이터 모으는 작업
- 정리, 시각화
단계는 이러하다.
https://developers.naver.com/docs/serviceapi/search/shopping/shopping.md#%EC%87%BC%ED%95%91
이 링크에서 사용법을 참고할 수 있다.
encText = urllib.parse.quote("몰스킨")
url = "https://openapi.naver.com/v1/search/shop?query=" + encText
이 부분을 직접 만들어주는 것이다
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
쇼핑에다 test라는 단어로, 3개까지 보여줘:
gen_search_url("shop", "TEST", 10, 3)
-> 하나의 완성된 url 형태로 결과를 받을 수 있다.
페이지에서 데이터를 받아오는 함수이다.
import json
import datetime
def get_result_onpage(url):
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) # 요청한 url 열어주기
print("[%s] Url Request Success" % datetime.datetime.now()) # 문자열 formatting으로 현재 시간 찍어줌
return json.loads(response.read().decode("utf-8"))
첫번째 페이지부터 5개를 보여줘:
url = gen_search_url("shop", "몰스킨", 1, 5)
one_result = get_result_onpage(url)
one_result(결과값)은 딕셔너리 형태로 확인 가능하다.
상품 정보는 items라는 key값에 담겨 있다.
one_result["items"]
이렇게 접근하면 되고,
첫번째 값을 보려면:
one_result["items"][0]
https://search.shopping.naver.com/product/42344941884 <- 이 다이어리다.
이런 식으로 원하는 정보를 추출할 수 있다.
가져온 정보들을 데이터프레임으로 만들어주는 함수를 만들자.
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", "lprice", "link", "mall"])
return result_pd
상품명, 구매링크, 가격, 쇼핑몰 이름 정보이다.
우리가 가져온 정보(one_result라는 변수에 담았음)를 get_fields함수에 넣어주면:
get_fields(one_result)
title을 보면
html 태그가 붙어서 나오는 이상한 형식이다.
replace를 이용하여 html 태그들을 제거해주는 함수를 만들었다.
def delete_tag(input_str):
input_str = input_str.replace("<b>", "")
input_str = input_str.replace("</b>", "")
return input_str
다시 get_fields 함수로 돌아와서 , title에 delete_tag 함수를 적용해 수정하였다.
def get_fields(json_data):
title = [delete_tag(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", "lprice", "link", "mall"])
return result_pd
get_fields(one_result)
제목의 태그를 다 제거하였다.
이제 합체 작업!!
1부터 1000까지 100단위로 총 10번 도는 반복문으로 데이터를 모아준다.
빈 리스트 만들어주고, 작업한 함수들을 모아서 정보를 얻어오고
얻어온 데이터 하나하나를 빈 리스트에 추가해주고,
데이터들을 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)
인덱스 바꿔주고... (index 라는 컬럼 없애기 (drop=True))
result_mol.reset_index(drop=True, inplace=True)
result_mol.info()
요청한 1000개의 데이터가 잘 모였다.
엑셀로 내보내기 전에, 가격 정보의 데이터타입을 숫자로 바꾸어주었다.
astype을 이용한다.
result_mol["lprice"] = result_mol["lprice"].astype("float")
result_mol.info()
xlsxwriter 없으면 설치하고~~
!pip install xlsxwriter
ExcelWriter와 to_excel로 엑셀파일 만들어주는데
sheets로 시트 이름 지정할 수 있고
set_column으로 열의 길이도 조절해서 title의 경우 보기 쉽게 설정했다.
conditional_format을 사용하여, 가격에 따라 배경색을 바꿔주는 조건부 서식(색조)을 지정해주었다.
writer = pd.ExcelWriter("../data/06. molskin_diary_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.save()
즉, 엑셀 작업을 파이썬 코드로 하나하나 해주는 작업들이다.
업무를 하는데 엑셀로 반복작업하는 게 많으면 파이썬으로 자동화하면 효율적이다!
시각화
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib import font_manager, rc
plt.rcParams["axes.unicode_minus"] = False
font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
rc('font', family=font_name)
%matplotlib inline
쇼핑몰 이름들이 다 겹쳐서 나옴 -> plt.xticks(rotation=90)로 이름들을 세워서 볼 수 있음
plt.figure(figsize=(15, 6))
sns.countplot(
result_mol["mall"],
data=result_mol,
palette="RdYlGn",
order=result_mol["mall"].value_counts().index
)
plt.xticks(rotation=90)
plt.show()