티스토리 뷰
Python/데이터 과학 기반의 파이썬 빅데이터 분석(한빛 아카데미)
데이터 과학 기반의 파이썬 빅데이터 분석 Chapter05 파이썬 크롤링-API 이용
아이언곰 2023. 1. 5. 23:46
01. 네이버 API를 이용한 크롤링
[CODE 0] 먼저, 전체 작업 스토리를 설계한다.
def main():
node = 'news' #크롤링할 대상
srcText = input('검색어를 입력하세요: ')
cnt = 0
jsonResult = []
jsonResponse = getNaverSearch(node, srcText, 1, 100) #[CODE 2]
total = jsonResponse['total']
while ((jsonResponse != None) and (jsonResponse['display'] != 0)):
for post in jsonResponse['items']:
cnt += 1
getPostData(post, jsonResult, cnt) #[CODE 3]
start = jsonResponse['start'] + jsonResponse['display']
jsonResponse = getNaverSearch(node, srcText, start, 100) #[CODE 2]
print('전체 검색: %d 건' %total)
with open('%s_naver_%s.json' % (srcText, node), 'w', encoding = 'utf8') as outfile:
jsonFile = json.dumps(jsonResult, indent = 4, sort_keys = True,
ensure_ascii = False)
outfile.write(jsonFile)
print("가져온 데이터 : %d 건" %(cnt))
print('%s_naver_%s.json SAVED' % (srcText, node))
[CODE 1] url 접속을 요청하고, 응답을 받아서 반환하는 부분을 작성한다.
def getResquestUrl(url):
req = urllib.request.Request(url)
req.add_header("X-Naver-Client-Id", client_id)
req.add_header("X-Naver-Client-Secret", client_secret)
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] Error for URL : %s" % (datetime.datetime.now(), url))
return None
[CODE2] 네이버 뉴스 검색 url을 만들고, [CODE1]의 getRequestURL(url)을 호출하여 반환받은 응답 데이터를 파이썬 json 형식으로 반환하는 부분이다.
def getNaverSearch(node, srcText, start, display):
base = "https://openapi.naver.com/v1/search"
node = "/%s.json" % node
parameters = "?query=%s&start=%s&display=%s" % (urllib.parse.quote(srcText), start, display)
url = base + node + parameters
responseDecode = getResquestUrl(url) #[CODE 1]
if (responseDecode == None):
return None
else:
return json.loads(responseDecode)
[CODE3] JSON 형식의 응답 데이터를 필요한 항목만 정리하여 딕셔너리 리스트인 jsonResult를 구성하고, 반환하도록 작성한다.
def getPostData(post, jsonResult, cnt):
title = post['title']
description = post['description']
org_link = post['originallink']
link = post['link']
pDate = datetime.datetime.strptime(post['pubDate'], '%a, %d %b %Y %H:%M:%S +0900')
pDate = pDate.strftime('%Y-%m-%d %H:%M:%S')
jsonResult.append({'cnt':cnt, 'title':title, 'description': description, 'org_link': org_link, 'link': org_link, 'pDate': pDate})
return
nvCrawler.py(전체 프로그램)
import os
import sys
import urllib.request
import datetime
import time
import json
client_id = '7gEpliLXF0aVmrsq7ffv'
client_secret = 'ScyStQ2AXP'
#[CODE1]
def getResquestUrl(url):
req = urllib.request.Request(url)
req.add_header("X-Naver-Client-Id", client_id)
req.add_header("X-Naver-Client-Secret", client_secret)
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] Error for URL : %s" % (datetime.datetime.now(), url))
return None
#[CODE2]
def getNaverSearch(node, srcText, start, display):
base = "https://openapi.naver.com/v1/search"
node = "/%s.json" % node
parameters = "?query=%s&start=%s&display=%s" % (urllib.parse.quote(srcText), start, display)
url = base + node + parameters
responseDecode = getResquestUrl(url) #[CODE 1]
if (responseDecode == None):
return None
else:
return json.loads(responseDecode)
#[CODE3]
def getPostData(post, jsonResult, cnt):
title = post['title']
description = post['description']
org_link = post['originallink']
link = post['link']
pDate = datetime.datetime.strptime(post['pubDate'], '%a, %d %b %Y %H:%M:%S +0900')
pDate = pDate.strftime('%Y-%m-%d %H:%M:%S')
jsonResult.append({'cnt':cnt, 'title':title, 'description': description, 'org_link': org_link, 'link': org_link, 'pDate': pDate})
return
#[CODE0]
def main():
node = 'news' #크롤링할 대상
srcText = input('검색어를 입력하세요: ')
cnt = 0
jsonResult = []
jsonResponse = getNaverSearch(node, srcText, 1, 100) #[CODE 2]
total = jsonResponse['total']
while ((jsonResponse != None) and (jsonResponse['display'] != 0)):
for post in jsonResponse['items']:
cnt += 1
getPostData(post, jsonResult, cnt) #[CODE 3]
start = jsonResponse['start'] + jsonResponse['display']
jsonResponse = getNaverSearch(node, srcText, start, 100) #[CODE 2]
print('전체 검색: %d 건' %total)
with open('%s_naver_%s.json' % (srcText, node), 'w', encoding = 'utf8') as outfile:
jsonFile = json.dumps(jsonResult, indent = 4, sort_keys = True,
ensure_ascii = False)
outfile.write(jsonFile)
print("가져온 데이터 : %d 건" %(cnt))
print('%s_naver_%s.json SAVED' % (srcText, node))
if __name__ == '__main__':
main()
검색어를 입력하세요: 월드컵
[2023-01-05 06:31:05.483106] Url Request Success
[2023-01-05 06:31:06.711095] Url Request Success
[2023-01-05 06:31:07.900064] Url Request Success
[2023-01-05 06:31:09.116239] Url Request Success
[2023-01-05 06:31:10.326584] Url Request Success
[2023-01-05 06:31:11.557006] Url Request Success
[2023-01-05 06:31:12.774514] Url Request Success
[2023-01-05 06:31:14.057419] Url Request Success
[2023-01-05 06:31:15.289108] Url Request Success
[2023-01-05 06:31:16.534831] Url Request Success
HTTP Error 400: Bad Request
[2023-01-05 06:31:17.438939] Error for URL : https://openapi.naver.com/v1/search/news.json?query=%EC%9B%94%EB%93%9C%EC%BB%B5&start=1001&display=100
전체 검색: 2769589 건
가져온 데이터 : 1000 건
월드컵_naver_news.json SAVED
02. 공공데이터 API 기반 크롤링
[CODE0] 전체 작업 스토리를 구성한다.
def main():
jsonResult = []
result = []
print("<< 국내 입국한 외국인의 통계 데이터를 수집합니다. >>")
nat_cd = input('국가 코드를 입력하세요(중국: 112 / 일본: 130 / 미국: 275) :')
nStartYear = int(input('데이터를 몇 년부터 수집할까요? : '))
nEndYear = int(input('데이터를 몇 년까지 수집할까요? : '))
ed_cd = "E" #E : 방한외래관광객, D: 해외 출국)
jsonResult, result, natName, ed, dataEND = getTourismStatsService(nat_cd, ed_cd, nStartYear, nEndYear) #[CODE 3]
#파일저장 1 : json 파일
with open('./%s_%s_%d_%s.json' % (natName, ed, nStartYear, dataEND), 'w', encoding='utf8') as outfile:
jsonFile = json.dumps(jsonResult, indent = 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')
[CODE1] url 접속을 요청하고, 응답을 받아서 반환한다.
def getRequestUrl(url):
req = urllib.request.Request(url)
try:
response = urllib.request.urlopen(req)
if response.getcode() == 200:
print("[%s] Url Resquest Success" % datetime.datetime.now())
return response.read().decode('utf-8')
except Exception as e:
print(e)
print("[%s] Error for URL : %s" % (datetime.datetime.now(), url))
return None
[CODE2] 출입국관광통계서비스의 오픈 API를 사용하여 데이터 요청 url을 만들고, [CODE1]의 getRequestUrl(url)을 호출해서 받은 응답 데이터를 반환한다.
def getTourismStatsItem(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
print(url) #액세스 거부 여부 확인용 출력
responseDecode = getRequestUrl(url) #[CODE1]
if (responseDecode == None):
return None
else:
return json.loads(responseDecode)
[CODE3] 수집 기간 동안 월 단위로 [CODE2]의 getTourismStatsItem()을 호출해 받은 데이터를 리스트로 묶어 반환한다.
def getTourismStatsService(nat_cd, ed_cd, nStartYear, nEndYear):
jsonResult = []
result = []
natName = ''
dataEND = "{0}{1:0>2}".format(str(nEndYear), str(12))
isDataEnd = 0
for year in range(nStartYear, nEndYear+1):
for month in range(1, 13):
if(isDataEnd == 1): break
yyyymm = "{0}{1:0>2}".format(str(year), str(month))
jsonData = getTourismStatsItem(yyyymm, nat_cd, ed_cd) #[CODE2]
if (jsonData['response']['header']['resultMsg'] == 'OK'):
if jsonData['response']['body']['items'] == '':
isDataEnd = 1
dataEND = "{0}{1:0>2}".format(str(year), str(month-1))
print("데이터 없음... \n 제공되는 통계 데이터는 %s년 %s월까지입니다." %(str(year), str(month-1)))
break
print(json.dumps(jsonData, indent = 4,
sort_keys = 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)
openapi_tour.py(전체 프로그램)
import os
import sys
import urllib.request
import datetime
import time
import json
import pandas as pd
ServiceKey = "KPgnUR%2FxcZK%2B9UjELd8AmigpgDzmRsOGqCtNRcINi8ZO0IZMjIAaPik7d6BeIIMd9pMmAwwFjKTHLkrjh321Dg%3D%3D"
#[CODE1]
def getRequestUrl(url):
req = urllib.request.Request(url)
try:
response = urllib.request.urlopen(req)
if response.getcode() == 200:
print("[%s] Url Resquest Success" % datetime.datetime.now())
return response.read().decode('utf-8')
except Exception as e:
print(e)
print("[%s] Error for URL : %s" % (datetime.datetime.now(), url))
return None
#[CODE2]
def getTourismStatsItem(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
print(url) #액세스 거부 여부 확인용 출력
responseDecode = getRequestUrl(url) #[CODE1]
if (responseDecode == None):
return None
else:
return json.loads(responseDecode)
#[CODE3]
def getTourismStatsService(nat_cd, ed_cd, nStartYear, nEndYear):
jsonResult = []
result = []
natName = ''
dataEND = "{0}{1:0>2}".format(str(nEndYear), str(12))
isDataEnd = 0
for year in range(nStartYear, nEndYear+1):
for month in range(1, 13):
if(isDataEnd == 1): break
yyyymm = "{0}{1:0>2}".format(str(year), str(month))
jsonData = getTourismStatsItem(yyyymm, nat_cd, ed_cd) #[CODE2]
if (jsonData['response']['header']['resultMsg'] == 'OK'):
if jsonData['response']['body']['items'] == '':
isDataEnd = 1
dataEND = "{0}{1:0>2}".format(str(year), str(month-1))
print("데이터 없음... \n 제공되는 통계 데이터는 %s년 %s월까지입니다." %(str(year), str(month-1)))
break
print(json.dumps(jsonData, indent = 4,
sort_keys = 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 = []
result = []
print("<< 국내 입국한 외국인의 통계 데이터를 수집합니다. >>")
nat_cd = input('국가 코드를 입력하세요(중국: 112 / 일본: 130 / 미국: 275) :')
nStartYear = int(input('데이터를 몇 년부터 수집할까요? : '))
nEndYear = int(input('데이터를 몇 년까지 수집할까요? : '))
ed_cd = "E" #E : 방한외래관광객, D: 해외 출국)
jsonResult, result, natName, ed, dataEND = getTourismStatsService(nat_cd, ed_cd, nStartYear, nEndYear) #[CODE 3]
#파일저장 1 : json 파일
with open('./%s_%s_%d_%s.json' % (natName, ed, nStartYear, dataEND), 'w', encoding='utf8') as outfile:
jsonFile = json.dumps(jsonResult, indent = 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()
<< 국내 입국한 외국인의 통계 데이터를 수집합니다. >>
국가 코드를 입력하세요(중국: 112 / 일본: 130 / 미국: 275) :112
데이터를 몇 년부터 수집할까요? : 2017
데이터를 몇 년까지 수집할까요? : 2021
http://openapi.tour.go.kr/openapi/service/EdrcntTourismStatsService/getEdrcntTourismStatsList?_type=json&serviceKey=KPgnUR%2FxcZK%2B9UjELd8AmigpgDzmRsOGqCtNRcINi8ZO0IZMjIAaPik7d6BeIIMd9pMmAwwFjKTHLkrjh321Dg%3D%3D&YM=201701&NAT_CD=112&ED_CD=E
[2023-01-05 08:10:31.469789] Url Resquest Success
{
"response": {
"body": {
"items": {
"item": {
"ed": "방한외래관광객",
"edCd": "E",
"natCd": 112,
"natKorNm": "중 국",
"num": 565243,
"rnum": 1,
"ym": 201701
}
},
"numOfRows": 10,
"pageNo": 1,
"totalCount": 1
},
"header": {
"resultCode": "0000",
"resultMsg": "OK"
}
}
}
[ 중국_201701 : 565243 ]
-------------------------------------------------
http://openapi.tour.go.kr/openapi/service/EdrcntTourismStatsService/getEdrcntTourismStatsList?_type=json&serviceKey=KPgnUR%2FxcZK%2B9UjELd8AmigpgDzmRsOGqCtNRcINi8ZO0IZMjIAaPik7d6BeIIMd9pMmAwwFjKTHLkrjh321Dg%3D%3D&YM=201702&NAT_CD=112&ED_CD=E
[2023-01-05 08:10:32.022056] Url Resquest Success
{
"response": {
"body": {
"items": {
"item": {
"ed": "방한외래관광객",
"edCd": "E",
"natCd": 112,
"natKorNm": "중 국",
"num": 590790,
"rnum": 1,
"ym": 201702
}
},
"numOfRows": 10,
"pageNo": 1,
"totalCount": 1
},
"header": {
"resultCode": "0000",
"resultMsg": "OK"
}
}
}
[ 중국_201702 : 590790 ]
-------------------------------------------------
.
.
.
-------------------------------------------------
http://openapi.tour.go.kr/openapi/service/EdrcntTourismStatsService/getEdrcntTourismStatsList?_type=json&serviceKey=KPgnUR%2FxcZK%2B9UjELd8AmigpgDzmRsOGqCtNRcINi8ZO0IZMjIAaPik7d6BeIIMd9pMmAwwFjKTHLkrjh321Dg%3D%3D&YM=202112&NAT_CD=112&ED_CD=E
[2023-01-05 08:11:04.334997] Url Resquest Success
{
"response": {
"body": {
"items": {
"item": {
"ed": "방한외래관광객",
"edCd": "E",
"natCd": 112,
"natKorNm": "중 국",
"num": 11691,
"rnum": 1,
"ym": 202112
}
},
"numOfRows": 10,
"pageNo": 1,
"totalCount": 1
},
"header": {
"resultCode": "0000",
"resultMsg": "OK"
}
}
}
[ 중국_202112 : 11691 ]
-------------------------------------------------
'Python > 데이터 과학 기반의 파이썬 빅데이터 분석(한빛 아카데미)' 카테고리의 다른 글
데이터 과학 기반의 파이썬 빅데이터 분석 Chapter09 지리 정보 분석 (0) | 2023.01.09 |
---|---|
데이터 과학 기반의 파이썬 빅데이터 분석 Chapter08 텍스트 빈도 분석 (0) | 2023.01.08 |
데이터 과학 기반의 파이썬 빅데이터 분석 Chapter07 통계분석 (0) | 2023.01.08 |
데이터 과학 기반의 파이썬 빅데이터 분석 Chapter06 파이썬 크롤링 - 라이브러리 이용 (0) | 2023.01.06 |
데이터 과학 기반의 파이썬 빅데이터 분석 Chapter04 파이썬 프로그래밍 기초 연습문제 (0) | 2023.01.05 |
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 프로그래밍
- Python
- 캐글
- SQL
- 머신러닝
- 데이터분석
- Kaggle
- 파이썬
- sql 테스트
- 쿼리 테스트
- Lv3
- mysql
- 프로그래머스
- LV2
- lv4
- API
- 데이터사이언스
- 알고리즘
- 부스트코스
- ai
- nlp
- 데이터 분석
- SQLD
- 태블로
- 딥러닝
- ML
- EDA
- 인공지능
- 데이터 시각화
- LV1
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함