2021. 12. 6. 23:50ㆍ토이 프로젝트/따릉이 토이 프로젝트
따릉이 프로젝트를 위해 가장 먼저 데이터 수집이 필요하여 서울특별시 공공자전거 실시간 대여정보를 활용하였다. 이제 작성할 구체적인 내용들은 지금 보면 매우 단순하지만 매우 많은 우여곡절이 있는 과정이였다.
1. Open API 불러올 코드 작성
위 페이지를 들어가서 설명을 읽어보면 제공하는 url을 호출하여 제공하는 데이터를 json 형식으로 받아올 수 있다고 한다. 이를 위해서는 인증키가 필요하여 인증키를 신청 후 데이터를 어떻게 불러올지에 대해 고민을 했다. 위 데이터의 설명을 보면 한번에 모든 정류장을 가져 오지 못하고 1000개 까지만 가져올 수 있다고 해서 그 부분도 고려하여 코드를 작성했다. 처음에는 5분 단위로 데이터를 불러오려고 했으나 데이터가 너무 많이 쌓여서 Google Data Studio에 활용할 시 대시보드가 자꾸 다운되는 현상이 발생해서 1시간 단위로 데이터를 불러오기로 정했다.
이렇게 한번에 깔끔하게 코드 작성이 완료되었다면 정말 좋았겠지만 도중에 알 수 없는 이유로 위 코드가 nohup에서 중단되는 경우가 정말 많았다. 가장 좋은 방법인지는 모르겠지만 에러가 발생할 수 있는 경우들을 예외 처리하기 위해 try except를 사용했다.
작성한 최종 코드는 다음과 같다.
from urllib.request import urlopen
import pandas as pd
import json
import datetime
import time
import pytz
import pymysql
# 서울 시간 설정
KST = pytz.timezone('Asia/Seoul')
certified_keys =
# aws rds 연결
def connetion():
global db
global cursor
db = pymysql.connect(host = ,
port = ,
user = ,
passwd = ,
db = ,
charset = 'utf8')
cursor = db.cursor(pymysql.cursors.DictCursor)
def getdata(now,certified_keys):
# API에 대한 응답이 빈 경우가 있어서, 빈 값이 온 경우 다시 API를 날리도록 만듦.
global result
result=[]
while True:
try:
# 따릉이 정류소가 계속 생겨서 10000개까지 API를 날려보게 함.
# 에러 메시지(정류소index가 없는 경우)가 나오면 pass하게 만듦.
for i in range(1,3000, 1000):
url = f'http://openapi.seoul.go.kr:8088/{certified_keys}/json/bikeList/{i}/{i+999}/'
response = urlopen(url)
results = response.read().decode("utf-8")
result = result + json.loads(results)['rentBikeStatus']['row']
# break전 부분에서 에러가 나기 때문에, break까지 갔다면 문제없이 데이터를 받아왔기 때문에 while문을 멈춤
break
except:
# 위의 try에서 문제가 생겼다면, except으로 오는데 여기서 continue를 만나면 다시 while의 첫 부분, try로 가게 되어
# 다시 API를 날리게 됨.
continue
# 위에서 받은 데이터를 필요한 정보만 추출 및 이중 리스트 형태로 변환
# executemany를 사용하기 위함
result=pd.DataFrame(data = result)
result = result[['rackTotCnt', 'parkingBikeTotCnt', 'shared', 'stationId']]
total_list = []
for i in range(len(result)):
total_list = total_list + [list(result.iloc[i,:])]
total_list[i].insert(0,now)
total_list[i].append(now.date())
total_list[i].append(now.time())
# db에 올리는 과정에서 에러가 나는 것을 방지
while True:
try:
connetion()
# rds에 입력할 쿼리
sql = "INSERT INTO bike_raw_table(datetime, rackTotCnt, parkingBikeTotCnt,shared,stationId, date, time) VALUES(%s,%s,%s,%s,%s,%s,%s)"
# 위의 쿼리를 한 정류장당 한번씩 올려두고 commit을 할 때 한번에 Table 업데이트.
# 이 중에서 정류장 위도와 경도, 한글 이름의 경우, 매 5분마다 중복되는 정보가 저장됨으로 따로 저장.
cursor.executemany(sql, total_list)
db.commit()
db.close()
break
except:
db.close()
continue
# 무한 반복문으로 ec2에 실행할 예정
while True:
# 시간을 계속 보다가, 분이 0이 되면 api 호출 + 데이터 rds에 저장
if datetime.datetime.now(KST).minute == 0:
getdata(datetime.datetime.now(KST), certified_keys)
# 너무 빨리 호출 및 데이터 저장이 이루어져, 같은 데이터가 2번씩 올라가는 경우가 있어
# 이를 방지하기 위해 2분 동안 동작을 멈춰놓음
time.sleep(120)
2. AWS EC2와 RDS 생성
사실 이 부분에서 가장 큰 위기가 왔었다. Open API를 호출하는 코드는 파이썬으로 작성하기 때문에 구글링하면서 작성을 했으나 AWS는 직접 다뤄본적이 전혀 없었기 때문이다. 다행히도 AWS 강의를 들으며 사용 경험이 있는 동기의 도움을 받아서 간신히 프리티어 AWS EC2와 RDS 생성을 완료했다. 설명을 들으며 완벽하게 이해한 내용은 EC2는 위에 작성한 코드를 실행시켜주는 역할이며 RDS는 그 실행 결과를 저장해주는 일종의 저장소라는 것이다.
3. Github 업로드와 ec2 git clone & nohup
위에 작성한 코드를 로컬 환경인 vscode에서 최종 확인 후 불러온 데이터가 AWS RDS에 정상적으로 적재되는 것을 확인 후 위 코드가 무한하게 돌아가도록 하는 과정이 필요하다. 이를 위해서는 github에 repository를 생성 후 위 파이썬 파일을 commit 진행하면 된다. 이 후에 AWS RDS를 생성하면서 받은 키페어가 있는 디렉토리에서 git bash here를 클릭 후 EC2에 로그인을 진행해야 한다. 로그인 완료 후 생성해둔 repository에 git clone를 진행하고 EC2에 파이썬 파일 실행에 필요한 패키지 및 라이브러리들을 모두 설치해야 한다. 이 과정들이 모두 끝나면 드디어 nohup 이라는 명령어를 이용해 파이썬 파일을 무한으로 실행 가능하다.
python3 nohup 파일명.py &
여기서 & 는 EC2를 종료해도 파일이 실행되도록 하는 명령어이다.
'토이 프로젝트 > 따릉이 토이 프로젝트' 카테고리의 다른 글
따릉이 프로젝트 - 분석을 위한 데이터 마이그레이션(AWS to GCP) (0) | 2021.12.21 |
---|---|
따릉이 프로젝트 - 대시보드 (0) | 2021.12.14 |
따릉이 프로젝트 - 추가 데이터 수집 (0) | 2021.12.08 |
따릉이 프로젝트 - 개요 (0) | 2021.12.06 |