호쌤
호쌤 Just For Fun

[Python] Pandas의 DataFrame과 데이터베이스 직접 연동

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

[Python] Pandas의 DataFrame과 데이터베이스 직접 연동

32-영화진흥원 박스오피스 데이터 수집, 저장

#01. 필요한 패키지 가져오기

1
2
3
4
5
6
7
8
import requests
import json
import datetime as dt
import pandas as pd
from pandas import DataFrame
import pymysql
from sqlalchemy import create_engine
from matplotlib import pyplot

#02. OpenAPI를 통한 데이터 수집

1) API Key 준비하기

1
api_key = "자신이 발급받은 연동키 사용"

2) 세션 생성

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} )

3) 접속 주소 준비하기

변수가 치환될 주소 템플릿

1
url_tpl = "http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key={key}&targetDt={date}"

조회날짜 문자열 만들기

여기서는 어제 날짜로 준비함

1
2
3
4
5
today = dt.datetime.now()                       # 오늘날짜
delta = dt.timedelta(days = -1)                 # 하루 전을 의미하는 timedelta객체
yesterday = today + delta                       # 오늘 날짜와 timedelta 연산
yesterday_str = yesterday.strftime("%Y%m%d")    # yyyymmdd 형식 문자열로 변환
yesterday_str
▶ 출력결과
1
'20200804'

최종 접속 주소 확인

1
2
api_url = url_tpl.format(key=api_key, date=yesterday_str)
api_url
▶ 출력결과
1
'http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=자신의_API_KEY&targetDt=20200804'

4) API를 통한 JSON 데이터 가져오기

OpenAPI를 통한 JSON 가져오기

1
2
3
4
5
6
7
8
r = session.get(api_url)

if r.status_code != 200:
    print("[%d Error] %s" % (r.status_code, r.reason))
    quit()

r.encoding = "utf-8"
r.text
▶ 출력결과
1
'{"boxOfficeResult":{"boxofficeType":"일별 박스오피스","showRange":"20200804~20200804","dailyBoxOfficeList":[{"rnum":"1","rank":"1","rankInten":"0","rankOldAndNew":"OLD","movieCd":"20196271","movieNm":"강철비2: 정상회담","openDt":"2020-07-29","salesAmt":"870081880","salesShare":"56.3","salesInten":"-60229660","salesChange":"-6.5","salesAcc":"10191695480","audiCnt":"106738","audiInten":"-7026","audiChange":"-6.2","audiAcc":"1240626","scrnCnt":"1945","showCnt":"8339"},{"rnum":"2","rank":"2","rankInten":"0","rankOldAndNew":"OLD","movieCd":"20193450","movieNm":"반도","openDt":"2020-07-15","salesAmt":"451255160","salesShare":"29.2","salesInten":"30010900","salesChange":"7.1","salesAcc":"30799788280","audiCnt":"55377","audiInten":"4124","audiChange":"8","audiAcc":"3545544","scrnCnt":"984","showCnt":"4123"},{"rnum":"3","rank":"3","rankInten":"0","rankOldAndNew":"OLD","movieCd":"20200491","movieNm":"빅샤크3: 젤리몬스터 대소동","openDt":"2020-07-29","salesAmt":"69939920","salesShare":"4.5","salesInten":"7389140","salesChange":"11.8","salesAcc":"381057960","audiCnt":"9461","audiInten":"1026","audiChange":"12.2","audiAcc":"49469","scrnCnt":"365","showCnt":"555"},{"rnum":"4","rank":"4","rankInten":"0","rankOldAndNew":"OLD","movieCd":"20183867","movieNm":"알라딘","openDt":"2019-05-23","salesAmt":"47529640","salesShare":"3.1","salesInten":"3127740","salesChange":"7","salesAcc":"107895621419","audiCnt":"6730","audiInten":"508","audiChange":"8.2","audiAcc":"12689400","scrnCnt":"284","showCnt":"546"},{"rnum":"5","rank":"5","rankInten":"1","rankOldAndNew":"OLD","movieCd":"20200162","movieNm":"소년시절의 너","openDt":"2020-07-09","salesAmt":"14731000","salesShare":"1.0","salesInten":"2395000","salesChange":"19.4","salesAcc":"529965700","audiCnt":"1752","audiInten":"294","audiChange":"20.2","audiAcc":"61732","scrnCnt":"81","showCnt":"136"},{"rnum":"6","rank":"6","rankInten":"1","rankOldAndNew":"OLD","movieCd":"20191048","movieNm":"온워드: 단 하루의 기적","openDt":"2020-06-17","salesAmt":"9564320","salesShare":"0.6","salesInten":"591300","salesChange":"6.6","salesAcc":"3542783640","audiCnt":"1241","audiInten":"108","audiChange":"9.5","audiAcc":"411748","scrnCnt":"76","showCnt":"101"},{"rnum":"7","rank":"7","rankInten":"1","rankOldAndNew":"OLD","movieCd":"20173901","movieNm":"존 윅: 특별판","openDt":"2017-03-30","salesAmt":"8512200","salesShare":"0.6","salesInten":"253600","salesChange":"3.1","salesAcc":"75368780","audiCnt":"1016","audiInten":"35","audiChange":"3.6","audiAcc":"8742","scrnCnt":"144","showCnt":"185"},{"rnum":"8","rank":"8","rankInten":"-3","rankOldAndNew":"OLD","movieCd":"20199883","movieNm":"오케이 마담","openDt":"2020-08-12","salesAmt":"7200000","salesShare":"0.5","salesInten":"-1210000","salesChange":"-14.4","salesAcc":"15610000","audiCnt":"850","audiInten":"-832","audiChange":"-49.5","audiAcc":"2532","scrnCnt":"7","showCnt":"7"},{"rnum":"9","rank":"9","rankInten":"2","rankOldAndNew":"OLD","movieCd":"20204644","movieNm":"밤쉘: 세상을 바꾼 폭탄선언","openDt":"2020-07-08","salesAmt":"6979520","salesShare":"0.5","salesInten":"2427920","salesChange":"53.3","salesAcc":"1497018760","audiCnt":"824","audiInten":"270","audiChange":"48.7","audiAcc":"175846","scrnCnt":"71","showCnt":"95"},{"rnum":"10","rank":"10","rankInten":"-1","rankOldAndNew":"OLD","movieCd":"20209107","movieNm":"세인트 주디 ","openDt":"2020-07-29","salesAmt":"6509380","salesShare":"0.4","salesInten":"1179280","salesChange":"22.1","salesAcc":"50308360","audiCnt":"813","audiInten":"122","audiChange":"17.7","audiAcc":"6213","scrnCnt":"138","showCnt":"160"}]}}'

JSON을 딕셔너리로 변환

1
2
daily_boxoffice_dict = json.loads(r.text)
daily_boxoffice_dict
▶ 출력결과
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{'boxOfficeResult': {'boxofficeType': '일별 박스오피스',
  'showRange': '20200804~20200804',
  'dailyBoxOfficeList': [{'rnum': '1',
    'rank': '1',
    'rankInten': '0',
    'rankOldAndNew': 'OLD',
    'movieCd': '20196271',
    'movieNm': '강철비2: 정상회담',
    'openDt': '2020-07-29',
    'salesAmt': '870081880',
    'salesShare': '56.3',
    'salesInten': '-60229660',
    'salesChange': '-6.5',
    'salesAcc': '10191695480',
    'audiCnt': '106738',
    'audiInten': '-7026',
    'audiChange': '-6.2',
    'audiAcc': '1240626',
    'scrnCnt': '1945',
    'showCnt': '8339'},
    ...생략...
  ]}}

딕셔너리를 데이터프레임으로 변환

1
2
daily_boxoffice_df = DataFrame(daily_boxoffice_dict['boxOfficeResult']['dailyBoxOfficeList'])
daily_boxoffice_df
▶ 출력결과
rnum rank rankInten rankOldAndNew movieCd movieNm openDt salesAmt salesShare salesInten salesChange salesAcc audiCnt audiInten audiChange audiAcc scrnCnt showCnt
0 1 1 0 OLD 20196271 강철비2: 정상회담 2020-07-29 870081880 56.3 -60229660 -6.5 10191695480 106738 -7026 -6.2 1240626 1945 8339
1 2 2 0 OLD 20193450 반도 2020-07-15 451255160 29.2 30010900 7.1 30799788280 55377 4124 8 3545544 984 4123
2 3 3 0 OLD 20200491 빅샤크3: 젤리몬스터 대소동 2020-07-29 69939920 4.5 7389140 11.8 381057960 9461 1026 12.2 49469 365 555
3 4 4 0 OLD 20183867 알라딘 2019-05-23 47529640 3.1 3127740 7 107895621419 6730 508 8.2 12689400 284 546
4 5 5 1 OLD 20200162 소년시절의 너 2020-07-09 14731000 1.0 2395000 19.4 529965700 1752 294 20.2 61732 81 136
5 6 6 1 OLD 20191048 온워드: 단 하루의 기적 2020-06-17 9564320 0.6 591300 6.6 3542783640 1241 108 9.5 411748 76 101
6 7 7 1 OLD 20173901 존 윅: 특별판 2017-03-30 8512200 0.6 253600 3.1 75368780 1016 35 3.6 8742 144 185
7 8 8 -3 OLD 20199883 오케이 마담 2020-08-12 7200000 0.5 -1210000 -14.4 15610000 850 -832 -49.5 2532 7 7
8 9 9 2 OLD 20204644 밤쉘: 세상을 바꾼 폭탄선언 2020-07-08 6979520 0.5 2427920 53.3 1497018760 824 270 48.7 175846 71 95
9 10 10 -1 OLD 20209107 세인트 주디 2020-07-29 6509380 0.4 1179280 22.1 50308360 813 122 17.7 6213 138 160

#05. 데이터 저장하기

1) 데이터베이스 접속하기

데이터베이스 연동에 필요한 접속 정보

1
2
3
4
5
6
7
HOSTNAME = "localhost"
PORT     = 3306
USERNAME = "root"
PASSWORD = "123qwe!@#"
DATABASE = "myschool"
CHARSET1  = "utf8"     # MySQL에서 사용할 캐릭터셋 이름
CHARSET2  = "utf-8"    # Python에서 사용할 캐릭터셋 이름

접속 문자열 생성

mysql+mysqldb://아이디:비밀번호@DB서버주소:포트번호/DB이름?charse=인코딩

1
2
3
con_str_fmt = "mysql+mysqldb://{0}:{1}@{2}:{3}/{4}?charset={5}"
con_str = con_str_fmt.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE, CHARSET1)
con_str
▶ 출력결과
1
'mysql+mysqldb://root:123qwe!@#@localhost:3306/myschool?charset=utf8'

pymysql을 사용하여 MySQL 연동 객체 설치하기

1
2
pymysql.install_as_MySQLdb()
import MySQLdb

데이터베이스 접속

1
2
engine = create_engine(con_str, encoding=CHARSET2)
conn = engine.connect()

2) 수집한 데이터 저장하기

1
2
3
daily_boxoffice_df.to_sql(name="daily_boxoffice",
                          con=conn, 
                          if_exists='replace', index=False)

3) 데이터베이스 접속 해제

1
conn.close()
Rating:

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

comments powered by Disqus