호쌤
호쌤 Just For Fun

[Python 데이터 수집] 카카오 Open API (2) - 책,블로그 검색 연습문제

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[Python 데이터 수집] 카카오 Open API (2) - 책,블로그 검색 연습문제≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

[Python 데이터 수집] 카카오 Open API (2) - 책,블로그 검색 연습문제

카카오개발자사이트에 로그인을 하고 난 후 발급받는 REST API Key를 사용하면 카카오 Open API를 통해 다음에서 제공되는 검색 결과를 수집할 수 있습니다.

API 연동에 필요한 스팩은 https://developers.kakao.com/docs/latest/ko/daum-search/dev-guide에서 확인 가능합니다.

#01. 책검색 API 연동 예제

카카오 OpenAPI의 책 검색 기능을 활용하여 파이썬이라는 키워드로 검색된 도서를 정확도 순으로 정렬하여 상위 100건을 수집하시오.

수집된 결과중에서 판매상태가 정상판매인 항목 중 상위 10건을 추출하여 제목, 저자, 출판사, 판매금액(정가), 할인가를 출력하고 판매금액(정가)의 총 합이 얼마인지 알아보시오.

1) 패키지 참조하기

1
2
3
4
5
import requests
import json    # 파이썬 기본 모듈
import urllib  # 파이썬 기본 모듈
import pandas as pd
from pandas import DataFrame

2) API 연동키 준비

1
api_key = "자신의 API Key"

3) 접속 세션 만들기

Kakao OpenAPI는 연동키를 헤더에 포함시켜야 한다.

1
2
3
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36"
session = requests.Session()
session.headers.update( {'User-agent': user_agent, 'referer': None, 'Authorization': 'KakaoAK ' + api_key} )

4) 접속할 주소 정의

1
url_tpl = "https://dapi.kakao.com/v3/search/book"

5) API에 전달할 파라미터 설정

1
2
3
q = "파이썬"    # 검색어
page = 1       # 접근할 페이지 번호(1~50)
size = 50      # 가져올 데이터 수 (1~80)

6) 데이터 수집하기

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
# 수집결과가 누적될 빈 리스트
documents = []

# 상위 100건을 가져오기 위해서는 한 페이지당 50건씩 2 페이지의 분량을 수집해야 한다.
for i in range(0, 2):
    # 페이지 번호 변수 준비
    page = i + 1
    
    # API에 전달할 파라미터
    params = {"page": page, "size": size, "query": q}
    query = urllib.parse.urlencode(params)
    #print(query)
    
    # 최종 접속 주소 구성하기
    api_url = url_tpl + "?" + query
    #print(api_url)
    
    # API 결과 가져오기
    r = session.get(api_url)

    if r.status_code != 200:
        print("[%d Error] %s" % (r.status_code, r.reason))
        quit()
    
    # 수집결과를 JSON으로 변경
    r.encoding = "utf-8"
    book_dict = json.loads(r.text)
    
    # 빈 리스트에 API에서 가져온 리스트를 병합
    documents += book_dict['documents']

6) 리스트를 데이터프레임으로 병합

1
2
3
# 수집 결과를 데이터프레임으로 생성
책검색df = DataFrame(documents)
책검색df
▶ 출력결과
authors contents datetime isbn price publisher sale_price status thumbnail title translators url
0 [모리 요시나오] 만화처럼 빨려 들어가는 비주얼한 프로그래밍 입문서 1학년 시리즈! 염소 박사님, 다... 2018-12-18T00:00:00.000+09:00 8931555687 9788931555684 17000 성안당 15300 정상판매 https://search1.kakaocdn.net/thumb/R120x174.q8... 파이썬(Python): 1학년 [이영란] https://search.daum.net/search?w=bookpage&book...
1 [한혁수] 『파이썬』은 비전공자들을 위한 파이썬 프로그래밍 교재다. 프로그래밍의 기본 개념을 ... 2016-08-31T00:00:00.000+09:00 8970508651 9788970508658 23000 생능출판사 20700 정상판매 https://search1.kakaocdn.net/thumb/R120x174.q8... 파이썬(창의적 프로그래밍을 위한) [] https://search.daum.net/search?w=bookpage&book...
2 [Y Daniel Liang] 이 책은 누구나 쉽게 따라할 수 있는 파이썬 프로그래밍 언어에 기반하고 있기 때문에... 2018-03-02T00:00:00.000+09:00 8920028893 9788920028892 35000 에피스테메 31500 정상판매 https://search1.kakaocdn.net/thumb/R120x174.q8... 파이썬 [길준민] https://search.daum.net/search?w=bookpage&book...
3 [천인국] 컴퓨팅 사고는 복잡한 문제를 분해하여 문제 안에 내재된 패턴을 찾고 추상화 단계를 ... 2017-08-30T00:00:00.000+09:00 1185578331 9791185578330 12000 인피니티북스 11400 정상판매 https://search1.kakaocdn.net/thumb/R120x174.q8... 파이썬(문제해결과 컴퓨팅 사고를 위한) [] https://search.daum.net/search?w=bookpage&book...
4 [최용] 『파이썬(Python) 3』은 쉽고 강력한 프로그래밍 언어인 파이썬에 대한 책이다.... 2014-02-12T00:00:00.000+09:00 1185578005 9791185578002 25000 인피니티북스 22500 정상판매 https://search1.kakaocdn.net/thumb/R120x174.q8... 파이썬(Python) 3(예제 중심의) [] https://search.daum.net/search?w=bookpage&book...
... ... ... ... ... ... ... ... ... ... ... ... ...
95 [존 하티] 있는 다양한 딥러닝 관련 대표 알고리즘들을 친절하고 자세하게 설명한다. 이미지 분류... 2017-08-17T00:00:00.000+09:00 1161750355 9791161750354 33000 에이콘출판 29700 정상판매 https://search1.kakaocdn.net/thumb/R120x174.q8... 파이썬으로 구현하는 고급 머신 러닝(acorn+PACKT 시리즈) [남궁영환] https://search.daum.net/search?w=bookpage&book...
96 [유채곤] 파이썬 프로그래밍 언어는 간결한 구조를 가지고 있어서 코딩이 편리하며 배우기도 쉬운... 2017-03-14T00:00:00.000+09:00 1127211420 1400000280195 9200 부크크(Bookk) 9200 정상판매 https://search1.kakaocdn.net/thumb/R120x174.q8... 초간단 파이썬 입문서 [] https://search.daum.net/search?w=bookpage&book...
97 [윤웅식] 이 책은 다른 프로그래밍 언어를 배운 적 있는 개발자가 파이썬 3를 빠르게 배울 수... 2017-11-01T00:00:00.000+09:00 1162240202 9791162240205 20000 한빛미디어 18000 정상판매 https://search1.kakaocdn.net/thumb/R120x174.q8... 개발자를 위한 파이썬 [] https://search.daum.net/search?w=bookpage&book...
98 [브라이언 칼링, 말리 아데어] 코딩이 지루하고 어렵게만 느껴지는 사람들을 위한 세상에서 제일 재미있는 파이썬 입문... 2018-09-10T00:00:00.000+09:00 8928643929 9788928643929 20000 코딩타임 18000 정상판매 https://search1.kakaocdn.net/thumb/R120x174.q8... 파이썬으로 시작하는 코딩 [민지현] https://search.daum.net/search?w=bookpage&book...
99 [문용준] 파이썬은 다양한 소프트웨어 개념을 수용해서 점진적으로 버전을 진화한 프로그래밍 언어... 2018-03-30T00:00:00.000+09:00 1186697571 9791186697573 44000 비제이퍼블릭 39600 정상판매 https://search1.kakaocdn.net/thumb/R120x174.q8... 손에 잡히는 파이썬 [] https://search.daum.net/search?w=bookpage&book...

100 rows × 12 columns

7) 문제 요구사항에 맞는 데이터 추출

판매 상태가 정상판매인 항목 추출

1
정상판매df = 책검색df.query('status=="정상판매"')

가격순으로 정렬

1
가격순df = 정상판매df.sort_values('price', ascending=False)

상위 10건 추출

1
상위10건df = 가격순df.head(10)

필요한 컬럼만 추출

1
2
결과df = 상위10건df.filter(['title', 'authors', 'publisher', 'price', 'sale_price'])
결과df
▶ 출력결과
title authors publisher price sale_price
24 전문가를 위한 파이썬 [루시아누 하말류] 한빛미디어 55000 49500
85 객체지향 파이썬 프로그래밍(acorn+PACKT 시리즈) [스티븐 로트] 에이콘출판 45000 40500
99 손에 잡히는 파이썬 [문용준] 비제이퍼블릭 44000 39600
41 파이썬을 활용한 금융 분석 [이브 힐피시] 한빛미디어 42000 37800
68 구글로 공부하는 파이썬 [김용재] 비제이퍼블릭 42000 37800
25 파이썬으로 배우는 알고리즘 트레이딩(위키북스 프로그래밍 & 프랙티스... [조대표] 위키북스 40000 36000
91 파이썬으로 배우는 인공지능(acorn+PACKT 시리즈) [프라틱 조쉬] 에이콘출판 40000 36000
43 러닝 파이썬(하)(5판) [마크 루츠] 제이펍 38000 34200
55 파이썬 데이터 사이언스 핸드북(데이터 사이언스 시리즈 5) [제이크 밴더플래스] 위키북스 38000 34200
59 러닝 파이썬(상)(5판) [마크 루츠] 제이펍 38000 34200

판매금액의 총 합

1
결과df['price'].sum()
▶ 출력결과
1
422000

#02. 블로그 검색 API 연동 예제

카카오 OpenAPI의 블로그 검색 기능을 활용하여 이태원코로나라는 키워드로 300개의 글을 검색한 결과를 수집하시오.

수집한 결과에서 본문만 추출하여 하나의 문자열로 병합한 뒤 그 결과를 활용하여 각 단어의 빈도수를 산출하여 자주 등장한 상위 100개 단어에 대한 워드클라우드를 생성하시오.

OpenAPI에 공백으로 구분하여 두 개 이상의 검색어를 전달할 수 있습니다.

1) 패키지 참조하기

위에서 먼저 참조한 패키지와 중복되지 않는 추가 패키지만 참조함

1
2
3
4
from wordcloud import WordCloud
from collections import Counter
from konlpy.tag import Okt
from IPython.display import Image

2) 접속할 주소 정의

1
url_tpl = "https://dapi.kakao.com/v2/search/blog"

3) 검색 파라미터 설정

1
2
3
q = "이태원 코로나"    # 검색어
page = 1             # 접근할 페이지 번호(1~50)
size = 50            # 가져올 데이터 수 (1~80)

4) 300건의 검색결과 수집

한 페이지에 최대 50건씩 이므로 총 6페이지의 검색 결과를 수집한다.

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
# 검색 결과에서 본문에 해당하는 값들을 누적할 빈 리스트 정의
content_list = []
    
for i in range(0,6):
    page = i + 1      # 1~6까지가 된다.
    
    # API에 전달할 파라미터 인코딩
    params = {"page": page, "size": size, "query": q}
    query = urllib.parse.urlencode(params)
    
    # 최종 접속 주소 구성
    api_url = url_tpl + "?" + query
    api_url
    
    # API에 접근하여 데이터 가져오기
    r = session.get(api_url)

    if r.status_code != 200:
        print("[%d Error] %s" % (r.status_code, r.reason))
        continue
        
    # 가져온 결과를 딕셔너리로 변환
    r.encoding = "utf-8"
    blog_dict = json.loads(r.text)

    # DataFrame 생성
    blog_df = DataFrame(blog_dict['documents'])
    
    # 내용에 해당하는 컬럼만 리스트로 추출하여 미리 준비한 리스트에 병합
    content_list += list(blog_df['contents'])
    
content_list
▶ 출력결과
1
2
3
4
5
6
['확진자가 많이 나오고 있지만 혹시나 같은 날짜에 저곳에 있었다면 일단 검사를 받아보는게 좋습니다. <b>이태원</b> <b>코로나</b> 확진자 어쨌든 지금은 <b>이태원</b>에 있는 킹클럽이라는 곳에 다녀온 사람들의 확진자수가 늘어나는 만큼 그것을 집중적으로 알아보도록 하겠습니다. <b>이태원</b> <b>코로나</b> 확진자 용인 66번 확진자 A씨는 5월...',
 '노력 사회적 거리두기 운동으로 <b>코로나</b> 19 바이러스 대처에 대해 전 세계적으로 모범사례로 뽑혔습니다. 이러한 노력에도 불구하고 최근 <b>이태원</b> <b>코로나</b> 확진자로 인해 다시금 <b>코로나</b> 19 바이러스가 국내에 유행하지 않을까 하는 근심이 밀려오기 시작했습니다. 그래서 이번 포스팅에서는 <b>이태원</b> <b>코로나</b> 확진자 동선에...',
 '앞으로 2주간(9일부터) &#39;클럽, 룸살롱, 노래바 등 모든 유흥주점을 비롯해 일반음식점 중 감성주점, 콜라텍&#39; 등에 집합 금지 조치를 한 것입니다. <b>이태원</b> 클럽 <b>코로나</b> 여기에 인천시와 대구시도 연이어 집합금지 명령을 내리며 <b>이태원</b> 클럽 <b>코로나</b> 사태로 인해 풍선효과를 막으려는 생각입니다. 만약 집단 금지 명령...',
 ... 생략 ...
 '안 기다림) \u200b \u200b \u200b \u200b 연휴 기간에 올해 처음 <b>이태원</b>을 다녀왔다 \u200b <b>이태원</b>에 사는 친구를 만나서 카페에서 신나게 얘기를 하고 1시간 가량 있다가 집에 왔다 \u200b 물론 오며...근무 + 검사 필수... \u200b \u200b ㅜ_ㅜ \u200b 하지만 막상 보건소들에 전화를 돌려보니 \u200b <b>코로나</b>19 감염 요인은 &#39;비말접촉&#39; 이기 때문에 <b>이태원</b> 클럽, 주점 등이...',
 '몇십명이 계속 늘고있는 상황입니다. 그리고 <b>이태원</b>클럽관련 접촉자들이 전국적으로 퍼지면서 제2차 지역감염이 시작되었습니다. 인천 <b>코로나</b> 지역감염 서울 <b>이태원</b> 클럽을 방문한 <b>코로나</b>19에 감염된 학원강사가 학생뿐만 아니라 학부모, 동료강사 등을 감염시켜 총 8명의 집단감염이 나왔습니다. 학생 6명, 학부모 1명...']

5) 리스트를 하나의 문자열로 병합

1
2
text = " ".join(content_list)
text
▶ 출력결과
1
2
3
'확진자가 많이 나오고 있지만 혹시나 같은 날짜에 저곳에 있었다면 일단 검사를 받아보는게 좋습니다. <b>이태원</b> <b>코로나</b> 확진자 어쨌든 지금은 <b>이태원</b>에 있는 킹클럽이라는 곳에 다녀온 사람들의 확진자수가 늘어나는 만큼 그것을 집중적으로 알아보도록 하겠습니다. <b>이태원</b> <b>코로나</b> 확진자 용인 66번 확진자 A씨는 5월... 노력 사회적 거리두기 운동으로 <b>코로나</b> 19 바이러스 대처에 대해 전 세계적으로 모범사례로 뽑혔습니다. 이러한 노력에도 불구하고 최근 <b>이태원</b> <b>코로나</b> 확진자로 인해 
... 생략 ...
상황입니다. 그리고 <b>이태원</b>클럽관련 접촉자들이 전국적으로 퍼지면서 제2차 지역감염이 시작되었습니다. 인천 <b>코로나</b> 지역감염 서울 <b>이태원</b> 클럽을 방문한 <b>코로나</b>19에 감염된 학원강사가 학생뿐만 아니라 학부모, 동료강사 등을 감염시켜 총 8명의 집단감염이 나왔습니다. 학생 6명, 학부모 1명...'

6) 형태소 분석

1
2
3
4
5
6
# 형태소 분석 클래스의 객체 생성
nlp = Okt()

# 명사들만 추출 -> 리스트형식으로 반환
nouns = nlp.nouns(text)
nouns
▶ 출력결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
['확',
 '진자',
 '혹시',
 '날짜',
 '곳',
 '일단',
 '검사',
 '이태원',
 '코로나',
 ... 생략 ...
 '가장',
 '먼저',
 '이태원',
 '클럽',
 '코로나',
 '확',
 '진자',
 ...]

7) 불필요한 단어 걸러내기

1
2
3
4
5
6
7
8
9
10
11
12
# 걸러낼 단어 정의
ignore = ['코로나', '코로나19', '이태원', '진자']

# 걸러낸 결과를 저장할 리스트
words = []

for n in nouns:
    # 걸러낼 단어에 포함되어 있지 않고, 글자수가 2글자 이상인 경우만 추출
    if n not in ignore and  len(n) > 1:
        words.append(n)
        
words
▶ 출력결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
['혹시',
 '날짜',
 '일단',
 '검사',
 '어쨌든',
 '지금',
 '클럽',
 '사람',
 ... 생략 ...
 '학교',
 '입장',
 '김수정',
 '클럽',
 '상당수',
 '무증상',
 '연락',
 '사람',
 ...]

8) 빈도수 검사후 상위 300건 추출

1
2
3
count = Counter(words)
most = count.most_common(100)
most
▶ 출력결과
1
2
3
4
5
6
7
8
9
10
11
12
[('클럽', 442),
 ('감염', 143),
 ('방문', 109),
 ('서울', 102),
 ('발생', 87),
 ... 생략 ...
 ('정말', 13),
 ('메이드', 13),
 ('박규리', 13),
 ('한국', 13),
 ('주말', 13),
 ('계속', 12)]

9) 워드 클라우드에 전달하기 위한 딕셔너리 구성

워드클라우드에 전달하기 위해서는 {"단어": 빈도수} 형식의 딕셔너리로 재구성 해야 한다.

1
2
3
4
5
6
7
8
9
10
tags = {}

# most의 원소들에 대한 반복 --> t는 (단어, 빈도수) 형식의 튜플
for t in most:
    # 튜플의 원소를 n과 c에 나누어 저장
    # --> n은 단어, c는 빈도수가 됨
    n, c = t

    # 미리 준비한 빈 딕셔너리에 {"단어": 빈도수} 형식으로 추가
    tags[n] = c

10) 워드 클라우드 생성

1
2
3
4
5
6
7
8
9
wc = WordCloud(font_path="NanumGothic", width=1200, height=800,
                scale=2.0, max_font_size=250, background_color="#ffffff")

# 직접 준비한 딕셔너리를 통해 생성
wc.generate_from_frequencies(tags)

filename = "%s.png" % q
wc.to_file(filename)
Image(filename)

png

Rating:

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[Python 데이터 수집] 카카오 Open API (2) - 책,블로그 검색 연습문제≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

comments powered by Disqus