💻프로그래밍/👩‍🔬빅데이터분석

공공데이터 API 기반 크롤링

hyerimmy 2021. 2. 15. 22:19

(오류발생-해결중)

import os
import sys
import urllib.request
import datetime
import time
import json
import pandas as pd

ServiceKey = "E%2BEwbzHXE%2FL77nVLKYMWrFXvZvVaFRPBmoIU1c2PcliTHKCUM5B%2BPI4AfludcbyFvrPi1zVxNxsrKnAdNuNEUw%3D%3D"

## [CODE1] : url 접속을 요청하고 응답을 받아 반환
def getRequestUrl(url):
    req = urllib.request.Request(url)
    try :
        response = urllib.request.urlopen(req)
        if response.getcode() == 200: #요청처리성공시
            print("[%s] Url Request Success" % datetime.datetime.now())
            return response.read().decode('utf-8')
    except Exception as e:
        print(e)
        print("[%s] Errpr fpr URL : %s" % (datetime.datetime.now(), url))
        return None

## [CODE2] : 출입국관광통계서비스 오픈API를 사용해 데이터 요청 url을 만들고 getRequestUrl을 호출해서 받은 응답 데이터 반환
def getTourismStartsItem(yyyymm, nat_cd, ed_cd):
    service_url = "http://openapi.tour.go.kr/openapi/service/EdrcntTourismStatsService/getEdrcntTourismStatsList"
    
    parameters = "?_type=json&serviceKey=" + ServiceKey #인증키
    parameters += "&YM=" + yyyymm
    parameters += "&NAT_CD=" + nat_cd
    parameters += "&ED_CD=" + ed_cd
    
    url = service_url + parameters
    
    responseDecode = getRequestUrl(url) #[CODE1]
    
    if (responseDecode == None):
        return None
    else:
        return json.loads(responseDecode)
        

## [CODE3] : 수집기간동안 월 단위로 getTourismStartsItem() 호출해 받은 데이터를 리스트로 묶어 반환
def getTourismStartsService(nat_cd, ed_cd, nStartYear, nEndYear):
    jsonResult = []
    result = []
    for year in range(nStartYear, nEndYear+1):
        for month in range(1,13):
            yyyymm = "{0}{1:0>2}".format(str(year), str(month))
            jsonData = getTourismStartsItem(yyyymm, nat_cd, ed_cd) #[CODE2]
            if(jsonData['response']['header']['resultMsg'] == 'OK'):
                #데이터가 없는 마지막 항목인 경우
                if jsonData['response']['body']['items'] == '':
                    dataEND = "{0}{1:0>2}".format(str(year), str(month-1))
                    print("데이터 없음.... \n 제공되는 통계 데이터는 %s년 %s월까지입니다."
                         %(str(year), str(month-1)))
                    break
                #jsonData를 출력하여 확인
                print(json.dumps(jsonData, indent=4, sortkeys=True, ensure_ascii=False))
                
                natName = jsonData['response']['body']['items']['item']['natKorNm']
                natName = natName.replace(' ','')
                num = jsonData['response']['body']['items']['item']['num']
                ed = jsonData['response']['body']['items']['item']['ed']
                print('[ %s_%s : %s ]' %(natName, yyyymm, num))
                print('--------------------------------------------------')
                jsonResult.append({'nat_name': natName, 'nat_cd':nat_cd, 'yyyymm': yyyymm, 'visit_cnt': num})
                result.append([natName, nat_cd, yyyymm, num])
            return (jsonResult, result, natName, ed, dataEND)


## [CODE0]
def main():
    jsonResult = [] #수집한데이터저장리스트객체, JSON파일저장용
    result = [] #수집한데이터저장리스트객체, csv파일저장용
    
    print("<< 국내 입국한 외국인의 통계 데이터를 수집합니다. >>")
    nat_cd = input('국가 코드를 입력하세요(중국: 112 / 일본: 130 / 미국: 275) : ') #데이터수집할 국가의 코드
    nStartYear = int(input('데이터를 몇 년부터 수집할까요? : '))
    nEndYear = int(input('데이터를 몇 년까지 수집할까요? : '))
    ed_cd = "E" # E : 방한외래관광객 / D : 해외출국
    
    jsonResult, result, natName, ed, dataEND = getTourismStartsService(nat_cd, ed_cd, nStartYear, nEndYear) # CODE3
    
    #파일저장 1 : json파일
    with open('./%s_%s_%d_%s.json' % (natName, ed, nStartYear, dataEND), 'w', encoding='utf8') as outfile :
        jsonFile = json.dumps(jsonResult, ident = 4, sort_keys = True, ensure_ascii = False)
        outfile.write(jsonFile)
        
    #파일저장 2 : csv파일
    columns = ["입국자국가", "국가코드", "입국연월", "입국자 수"]
    result_df = pd.DataFrame(result, columns = columns)
    result_df.to_csv('./%s_%s_%d_%s.csv' % (natName, ed, nStartYear, dataEND), index = False, encoding = 'cp949')
    
if __name__ == '__main__':
    main()