1. Naver API
1.1 API
- API : Application Programming Interface
- 네이버, 페이스북, 구글 등 IT 거대 기업들과 같은 많은 SW관련 회사들이 자사 서비스와 관련한 API를 제공함
- 웹 크롤링에 대한 법적 문제가 대두되고 있는 상황에 따라 해당 회사에서 제공하는 API를 사용하는것이 바람직 할수 있다
- 우리는 점점 API의 사용에 익숙해 질 필요가 있다
1.2 Naver 개발자 센터
- https://developers.naver.com/main/
- 네이버 로그인 후 위 링크에서 서비스 API 클릭
- 데이터랩 -> Open API 이용 신청
- 애플리케이션 이름은 편한대로 등록
- 사용 API는 사용할것 등록(검색어트랜드, 쇼핑인사이트 등)
- Web설정은 http://locallhost 로 한 후 등록 (웹사이트가 없으므로)
- 내 애플리케이션에서 애플리케이션 정보(Client ID, Client Secreat) 를 잘 보관해야함(API를 받을때 사용함)
- 일일 사용량은 정해져 있음
1.3 네이버 블로그 API 호출
1
2
3
4
5
6
7
8
9
10
11
12
import urllib.request
client_id = 'Your client_id' # Your client_id
client_secret = 'Your client_secret' # Your client_secret
encText = urllib.parse.quote('파이썬')
url = "https://openapi.naver.com/v1/search/blog?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)
print(response.read().decode('utf-8'))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"lastBuildDate": "Thu, 15 Oct 2020 15:11:16 +0900",
"total": 176910,
"start": 1,
"display": 10,
"items": [
{
"title": "<b>파이썬</b>(Phython)이 스타트업에게 인기있는 이유 7가지",
"link": "http://blog.wishket.com/%ED%8C%8C%EC%9D%B4%EC%8D%ACpython%EC%9D%B4-%EC%8A%A4%ED%83%80%ED%8A%B8%EC%97%85%EC%97%90%EA%B2%8C-%EC%9D%B8%EA%B8%B0%EC%9E%88%EB%8A%94-%EC%9D%B4%EC%9C%A0-7%EA%B0%80%EC%A7%80/",
"description": "<b>파이썬</b>(Python)이 스타트업에게 인기있는 이유 7가지 Facebook Twitter 안녕하세요. 위시켓입니다.... 그렇기 때문에 <b>파이썬</b>(Python)과 같은 강력하면서도 기반이 튼튼한 기술을 사용하는 것이 가장 좋습니다.... ",
"bloggername": "그린 클라이언트 – Wishket",
"bloggerlink": "http://blog.wishket.com/",
"postdate": "20200831"
},
{
"title": "<b>파이썬</b> 학원 확연히 다른 스킬 강좌!",
"link": "https:\/\/blog.naver.com\/hmiya00?Redirect=Log&logNo=222114719683",
"description": "오늘은 <b>파이썬</b> 학원을 소개해 드릴까 합니다. 저는 어렸을 때부터 기계나 컴퓨터에 관심이 많았어요.... 다행히 제가 다녔던 <b>파이썬</b> 학원은 국비 지원을 통해 금전적인 부담을 조금 덜고 수업을 들을 수 있어서... ",
"bloggername": "한시라도 빨리 떠나시게",
"bloggerlink": "https://blog.naver.com/hmiya00",
"postdate": "20201013"
}
...
]
}
- url : 네이버 블로그 검색 결과를 가져오는 주소
- urllib : http 프로토콜에 따라서 서버의 요청/응답을 처리하기 위한 모듈
- urllib.request : 클라이언트의 요청을 처리하는 모듈
- urllib.parse : url 주소에 대한 분석
- print(response.read().decode(‘utf-8’)) : 검색 결과 출력, decode를 utf-8로 해야함
1.4 에러코드 확인
- 에러코드 SE01 : 검색 API 요청에 오류가 있음
- 에러코드 SE06 : 검색어를 UTF-8로 인코딩
2. API 실습
2.1 네이버 책 API
1
2
3
4
5
6
7
8
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)
print(response.read().decode('utf-8'))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
{
"lastBuildDate": "Thu, 15 Oct 2020 15:27:12 +0900",
"total": 1046,
"start": 1,
"display": 10,
"items": [
{
"title": "핸즈온 <b>머신러닝</b>(2판) (사이킷런, 케라스, 텐서플로 2를 활용한 <b>머신러닝</b>, 딥러닝 완벽 실무)",
"link": "http://book.naver.com/bookdb/book_detail.php?bid=16328592",
"image": "https://bookthumb-phinf.pstatic.net/cover/163/285/16328592.jpg?type=m1&udate=20201005",
"author": "오렐리앙 제롱",
"price": "55000",
"discount": "49500",
"publisher": "한빛미디어",
"pubdate": "20200504",
"isbn": "1162242965 9791162242964",
"description": "컬러판으로 돌아온 아마존 인공지능 분야 부동의 1위 도서\n이 책은 지능형 시스템을 구축하려면 반드시 알아야 할 <b>머신러닝</b>, 딥러닝 분야 핵심 개념과 이론을 이해하기 쉽게 설명한다. 사이킷런, 케라스, 텐서플로를 이용해 실전에서 바로 활용 가능한 예제로 모델을 훈련하고 신경망을 구축하는 방법을... "
},
{
"title": "파이썬 <b>머신러닝</b> 완벽 가이드 (다양한 캐글 예제와 함께 기초 알고리즘부터 최신 기법까지 배우는)",
"link": "http://book.naver.com/bookdb/book_detail.php?bid=16238302",
"image": "https://bookthumb-phinf.pstatic.net/cover/162/383/16238302.jpg?type=m1&udate=20200423",
"author": "권철민",
"price": "38000",
"discount": "34200",
"publisher": "위키북스",
"pubdate": "20200207",
"isbn": "1158391927 9791158391928",
"description": "자세한 이론 설명과 파이썬 실습을 통해 <b>머신러닝</b>을 완벽하게 배울 수 있습니다!《파이썬 <b>머신러닝</b> 완벽 가이드》는 이론 위주의 <b>머신러닝</b> 책에서 탈피해 다양한 실전 예제를 직접 구현해 보면서 <b>머신러닝</b>을 체득할 수 있도록 만들었습니다. 캐글과 UCI <b>머신러닝</b> 리포지토리에서 난이도가 있는 실습... "
},
...
]
}
- 네이버책에서 머신러닝 제목을 가진 책을 받아옴 총 1046개이다
- display는 10개가 제한으로, 총 10개만 나오게 됨
- 위의 블로그 API 검색 url에서 마지막 부분의 blog가 book으로 바뀌었다
2.2 네이버 영화 API
1
2
3
4
5
6
7
8
encText = urllib.parse.quote('엔드게임')
url = 'https://openapi.naver.com/v1/search/movie?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)
print(response.read().decode('utf-8'))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"lastBuildDate": "Thu, 15 Oct 2020 15:59:22 +0900",
"total": 13,
"start": 1,
"display": 10,
"items": [
{
"title": "이벤트 트렌스파이어링 비포, 듀링, <b>엔드</b> 애프터 어 하이 스쿨 바스켓볼 <b>게임</b>",
"link": "https://movie.naver.com/movie/bi/mi/basic.nhn?code=197237",
"image": "https://ssl.pstatic.net/imgmovie/mdi/mit110/1972/197237_P01_111704.jpg",
"subtitle": "Events Transpiring Before, During, and After a High School Basketball Game",
"pubDate": "2020",
"director": "테드 스텐슨|",
"actor": "",
"userRating": "0.00"
},
...
]
}
- 엔드게임이라는 영화제목을 검색해봄
2.3 네이버카페 API
1
2
3
4
5
6
7
8
encText = urllib.parse.quote('파이썬')
url = 'https://openapi.naver.com/v1/search/cafearticle?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)
print(response.read().decode('utf-8'))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"lastBuildDate": "Thu, 15 Oct 2020 16:00:58 +0900",
"total": 90077,
"start": 1,
"display": 10,
"items": [
{
"title": "<b>파이썬</b> 코딩 빠르게 할려면?",
"link": "http://cafe.naver.com/fx8300/698502",
"description": "지난번에 <b>파이썬</b> 코딩하는데 자기 놋북으로 10시간 걸린다고 거실 데탑으로 해 보더니 2시간 걸리더라구요. <b>파이썬</b> 코딩 좀 빠르게 할려면 오버 안한다는 조건으로 어떤걸로 업하면 체감이 될런지.. 현재 라이젠5... ",
"cafename": "AMD 비쉐라 라이젠 컴퓨터 사용자 모임",
"cafeurl": "https://cafe.naver.com/fx8300"
},
]
}
- 파이썬이라는 이름으로 네이버카페를 검색했을때 나오는 내용
2.4 네이버 쇼핑 API
1
2
3
4
5
6
7
8
encText = urllib.parse.quote('파이썬')
url = 'https://openapi.naver.com/v1/search/shop?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)
print(response.read().decode('utf-8'))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"lastBuildDate": "Thu, 15 Oct 2020 16:02:01 +0900",
"total": 197549,
"start": 1,
"display": 10,
"items": [
{
"title": "글렌다블룸 리얼 <b>파이톤</b> 미니 보스톤백",
"link": "https://search.shopping.naver.com/gate.nhn?id=24198320022",
"image": "https://shopping-phinf.pstatic.net/main_2419832/24198320022.20200918175522.jpg",
"lprice": "142170",
"hprice": "151370",
"mallName": "네이버",
"productId": "24198320022",
"productType": "1",
"brand": "",
"maker": "",
"category1": "패션잡화",
"category2": "여성가방",
"category3": "토트백",
"category4": ""
},
...
]
}
- 네이버 쇼핑의 파이썬 검색
2.5 백과사전 API
1
2
3
4
5
6
7
8
encText = urllib.parse.quote('파이썬')
url = 'https://openapi.naver.com/v1/search/encyc?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)
print(response.read().decode('utf-8'))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"lastBuildDate": "Thu, 15 Oct 2020 16:03:08 +0900",
"total": 426,
"start": 1,
"display": 10,
"items": [
{
"title": "<b>파이썬</b>",
"link": "https://terms.naver.com/entry.nhn?docId=3580815&cid=59088&categoryId=59096",
"description": "‘<b>파이썬</b>’이다. 간결한 문법으로 입문자가 이해하기 쉽고, 다양한 분야에 활용할 수 있기 때문이다. 이 외에도 <b>파이썬</b>은 머신러닝, 그래픽, 웹 개발 등 여러 업계에서 선호하는 언어로 꾸준히... ",
"thumbnail": "http://openapi-dbscthumb.phinf.naver.net/4749_000_1/20170118193349632_0CHSSS5Y6.png/01_16.png?type=m160_160"
},
]
}
- 백과사전 검색
3. 네이버쇼핑 API에서 몰스킨 상품 받아서 저장하기
3.1 몰스킨?
- 창조적인 일을 하는 사람들이, 창조성을 기록하는 책의 이미지
- 전세계의 많은 사람들이 몰스킨의 제품으로 기록을 하고 있다.
3.2 순서도
- 1) URL 생성
- 2) URL을 API에 적용
- 3) 데이터프레임으로 변경하여 저장
- 4) 여러페이지에 적용
- 5) 엑셀로 저장
- 순서도를 미리 작성하여 코드의 흐름을 잡고, 체계적으로 개발을 할수 있도록 하자
3.3 검색 URL 생성
1
2
3
4
5
6
7
8
def get_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에 포함되어야하는 파라미터들의 설명
요청 | 변수명 | 타입 | 필수여부 | 기본값설명 |
---|---|---|---|---|
query | string | Y | - | 검색을 원하는 문자열로서 UTF-8로 인코딩한다. |
display | integer | N | 10(기본값), 100(최대) | 검색 결과 출력 건수 지정 |
start | integer | N | 1(기본값), 1000(최대) | 검색 시작 위치로 최대 1000까지 가능 |
sort | string | N | sim(기본값), date, asc, dsc | 정렬 옵션: sim (유사도순), date (날짜순), asc(가격오름차순) ,dsc(가격내림차순) |
- 해당 파라미터들을 포함하는 url 생성기를 함수로 작성
1
get_search_url('shop', 'test', 10,3)
1
'https://openapi.naver.com/v1/search/shop.json?query=test&start=10&display=3'
- 네이버 쇼핑(shop), test라는 검색어에 10번째 페이지에서 3개의 데이터만 가져오는 URL을 생성
3.4 URL을 API에 적용
1
2
3
4
5
6
7
8
9
10
11
12
13
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을 입력받아, 해당 URL을 API에 적용시켜 json 형태로 저장하는 함수를 작성
- client_id, client_secret은 맨위에 api 신청하며 받은 본인의 것을 넣으면 됨
3.5 중간 테스트
1
2
3
4
5
6
client_id = 'your_id' # your_id
client_secret = 'your_secret' # your_secret
url = get_search_url('shop', '몰스킨', 1, 2)
one_result = get_result_onpage(url)
one_result
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[2020-10-15 16:31:32.135759] Url Request Success
{'lastBuildDate': 'Thu, 15 Oct 2020 16:31:32 +0900',
'total': 36615,
'start': 1,
'display': 2,
'items': [{'title': '<b>몰스킨</b> <b>몰스킨</b> 2021 데일리 12M 다이어리 소프트커버 라지 사파이어블루',
'link': 'https://search.shopping.naver.com/gate.nhn?id=24014109279',
'image': 'https://shopping-phinf.pstatic.net/main_2401410/24014109279.20200903005345.jpg',
'lprice': '21130',
'hprice': '38500',
'mallName': '네이버',
'productId': '24014109279',
'productType': '1',
'brand': '몰스킨',
'maker': '몰스킨',
'category1': '생활/건강',
'category2': '문구/사무용품',
'category3': '다이어리/플래너',
'category4': '다이어리'},
{'title': '<b>몰스킨</b> 2021 다이어리 데일리 위클리 먼슬리 A5 고급 명품 감성 업무용 회사 기업 각인',
'link': 'https://search.shopping.naver.com/gate.nhn?id=82635708485',
'image': 'https://shopping-phinf.pstatic.net/main_8263570/82635708485.jpg',
'lprice': '24100',
'hprice': '0',
'mallName': '에코펜',
'productId': '82635708485',
'productType': '2',
'brand': '몰스킨',
'maker': '몰스킨',
'category1': '생활/건강',
'category2': '문구/사무용품',
'category3': '다이어리/플래너',
'category4': '다이어리'}]}
- 몰스킨의 제품 2개를 가져와보았고, 제대로 출력이됨
1
2
print(one_result['items'][0]['title'])
print(one_result['items'][0]['lprice'])
1
2
<b>몰스킨</b> <b>몰스킨</b> 2021 데일리 12M 다이어리 소프트커버 라지 사파이어블루
21130
- API로 받은 데이터는 items에 저장되어있으며, 첫번째 상품의 이름과 가격을 출력해보았음
3.6 데이터프레임으로 변경하여 저장
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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']]
hprice = [each['hprice'] for each in json_data['items']]
mall_name = [each['mallName'] for each in json_data['items']]
result_pd = pd.DataFrame({'title': title, 'lprice': lprice, 'hprice': hprice, 'link': link,
'mall': mall_name}, columns=['title', 'lprice', 'hprice', 'link', 'mall'])
return result_pd
- json 포멧의 데이터를 데이터프레임으로 변경하는 함수를 작성하였음
1
get_fields(one_result)
- 실제로 적용해보니
<b>
태그가 같이 나옴
1
2
3
4
5
def delete_tag(input_str):
input_str = input_str.replace('<b>', '')
input_str = input_str.replace('</b>', '')
return input_str
<b>
태그를 없애는 함수를 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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']]
hprice = [each['hprice'] for each in json_data['items']]
mall_name = [each['mallName'] for each in json_data['items']]
result_pd = pd.DataFrame({'title': title, 'lprice': lprice, 'hprice': hprice, 'link': link,
'mall': mall_name}, columns=['title', 'lprice', 'hprice', 'link', 'mall'])
return result_pd
- 위에서 만든 태그 제거기를 title을 만들때 적용
1
2
3
4
url = get_search_url('shop', '몰스킨', 1, 3)
json_result = get_result_onpage(url)
pd_result = get_fields(json_result)
pd_result
1
[2020-10-15 16:41:44.523438] Url Request Success
<b>
태그 없이 잘 나옴- 중간 테스트 완료
3.7 여러 페이지에 적용
1
2
for n in range(1, 500, 100):
print(n)
1
2
3
4
5
1
101
201
301
401
- 왜 이러냐면은 위의 제한조건을 보면 알겠지만 display는 100개의 제한이 있다.
- 따라서 100개 이상의 제품을 API로 받아오려면 여러번 반복해야하고, 이를 for문으로 구현하겠다는 이야기
1
2
3
4
5
6
7
8
9
10
11
result_mol = []
for n in range(1, 1000, 100):
url = get_search_url('shop', '"몰스킨"', n, 100)
one_result = get_result_onpage(url)
pd_result = get_fields(one_result)
result_mol.append(pd_result)
result_mol = pd.concat(result_mol)
result_mol.tail()
1
2
3
4
5
6
7
8
9
10
[2020-10-15 16:47:31.030728] Url Request Success
[2020-10-15 16:47:31.290818] Url Request Success
[2020-10-15 16:47:31.444291] Url Request Success
[2020-10-15 16:47:31.747240] Url Request Success
[2020-10-15 16:47:32.036682] Url Request Success
[2020-10-15 16:47:32.185240] Url Request Success
[2020-10-15 16:47:32.346305] Url Request Success
[2020-10-15 16:47:32.487543] Url Request Success
[2020-10-15 16:47:32.635507] Url Request Success
[2020-10-15 16:47:32.781476] Url Request Success
- 총 10번을 진행하여, 1000개의 몰스킨 상품의 정보를 가져왔음
- 몰스킨은 꼭
쌍따옴
표로 감싸서 진행해야함
1
result_mol.info()
1
2
3
4
5
6
7
8
9
10
11
12
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000 entries, 0 to 99
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 title 1000 non-null object
1 lprice 1000 non-null object
2 hprice 1000 non-null object
3 link 1000 non-null object
4 mall 1000 non-null object
dtypes: object(5)
memory usage: 46.9+ KB
- 1000개의 데이터인데, 인덱스를 보면 0 ~ 99까지로 총 100번 된듯 하다
1
2
result_mol.reset_index(drop = True, inplace = True)
result_mol.info()
1
2
3
4
5
6
7
8
9
10
11
12
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 title 1000 non-null object
1 lprice 1000 non-null object
2 hprice 1000 non-null object
3 link 1000 non-null object
4 mall 1000 non-null object
dtypes: object(5)
memory usage: 39.2+ KB
- reset_index로 바로 잡아줌
1
result_mol.tail()
- index가 999로 나오는것을 보니 제대로 바뀐것 같다
1
2
3
result_mol['lprice'] = result_mol['lprice'].astype('float')
result_mol['hprice'] = result_mol['hprice'].astype('float')
result_mol.info()
1
2
3
4
5
6
7
8
9
10
11
12
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 title 1000 non-null object
1 lprice 1000 non-null float64
2 hprice 1000 non-null float64
3 link 1000 non-null object
4 mall 1000 non-null object
dtypes: float64(2), object(3)
memory usage: 39.2+ KB
- 가격은 실수형으로 변환
3.8 엑셀로 저장
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import datetime
writer = pd.ExcelWriter('data/molskin_navershopAPI.xlsx', engine='xlsxwriter')
today = datetime.datetime.today().strftime("%Y%m%d")
result_mol.to_excel(writer, sheet_name=today)
workbook = writer.book
worksheet = writer.sheets[today]
worksheet.set_column('A:A', 4)
worksheet.set_column('B:B', 65)
worksheet.set_column('C:C', 10)
worksheet.set_column('D:D', 10)
worksheet.set_column('E:E', 50)
worksheet.set_column('F:F', 15)
worksheet.conditional_format('C2:C1001', {'type' : '3_color_scale'})
writer.save()
- 위 처럼 엑셀이 만들어지게 된다.
- today : API를 받아 엑셀을 생성한 날짜를 sheet name으로 설정
- set_column : 각 컬럼의 크기를 셋팅
- conditional_format : 컬럼의 색상을 변경함