참고
- urllib : http 프로토콜에 따라서 서버의 요청/응답을 처리하기 위한 모듈
- urllib.request : 클라이언트 요청을 처리하는 모듈
- urllib.parse : url 주소에 대한 분석
import os
import sys
import urllib.request
client_id = "oc~~~AA"
client_secret = "~"
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)

import os
import sys
import urllib.request
client_id = "oc~~~AA"
client_secret = "~"
encText = urllib.parse.quote("파이썬")
url = "https://openapi.naver.com/v1/search/book?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 주소에서 검색 대상 엔진을 밑줄 자리만 변경해주면 된다.
response, response.getcode(), response.code, response.status
# (<http.client.HTTPResponse at 0x1de67946700>, 200, 200, 200)
# url = "https://openapi.naver.com/v1/search/shop?query=" + encText
# 위 url 주소 형식에 맞게 url 함수 작성
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
gen_search_url('shop', 'TEST', 10, 3)
# 'https://openapi.naver.com/v1/search/shop.json?query=TEST&start=10&display=3'
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)
print("[%s] Url Request Success" % datetime.datetime.now())
return json.loads(response.read().decode("utf-8"))
url = gen_search_url('shop', '몰스킨', 1, 5)
one_result = get_result_onpage(url)
# [2023-04-05 16:29:43.467307] Url Request Success
one_result

print(one_result['items'][0]['title'])
# '<b>몰스킨</b> 노트 가죽 하드커버 감성 고급 업무용 이쁜 심플'
print(one_result['items'][0]['link'])
# 'https://search.shopping.naver.com/gate.nhn?id=82526953942'
print(one_result['items'][0]['mallName'])
# '베스트펜'
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
get_fields(one_result)

→ 태그가 같이 추출된 결과를 볼 수 있다. 태그를 지우는 함수를 설정해줘야한다.
def delete_tag(input_str):
input_str = input_str.replace("<b>", "")
input_str = input_str.replace("</b>", "")
return input_str
import pandas as pd
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)

→ 'title'컬럼만 태그가 같이 추출됐으므로 'title'에 태그를 지우는 함수를 적용하고 재수행해보니 태그가 삭제된 형태로 출력됐다.
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.info()

→ 1000개의 데이터이므로 인덱스 범위는 '0 to 999'로 나타나야하는데 99까지 나왔으므로, 인덱스를 재설정 해줘야한다. 또한 추후 가격을 비교하는 시각화를 나타낼 수 있기때문에 float 데이터형태로 변환시켜준다.
result_mol.reset_index(drop=True, inplace=True)
result_mol['lprice'] = result_mol['lprice'].astype(float)
result_mol.info()

!pip install xlsxwriter
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'] # 워크시트 이름을 'Sheet1'으로 설정
worksheet.set_column('A:A', 4) # '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
import platform
from matplotlib import font_manager, rc
path = 'C:/Windows/Fonts/malgun.ttf'
if platform.system == 'Darwin':
rc('font', family='Arial Unicode MS')
print('Hangul OK in your MAC!!')
elif platform.system() == 'Windows':
font_name = font_manager.FontProperties(fname=path).get_name()
rc('font', family=font_name)
print('Hangul OK in your Windows!!')
else:
print('Unkown system. sorry')
result_mol

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

→ '네이버' 몰의 판매가 압도적으로 높다.
"이 글은 제로베이스 데이터 취업 스쿨의 강의 자료 일부를 발췌하여 작성되었습니다."