728x90
반응형

 

공공데이터포털 데이터 가져오기

내가 사용하기로한 공공데이터포털의 데이터("서울교통공사_지하철혼잡도정보")를 가져오기 위해서 제공하는 API 를 통해 데이터를 가져올 수 있다. 포털에서 API 를 생성할 수 있도록 제공해주는 기능이 있는데 인증키를 등록하고 API 를 호출할 수 있는 URL 을 생성해준다.

 

그래서 다음과 같이 URL 을 실행하면 다음과 같이 데이터를 확인할 수 있다.

curl -X GET "https://api.odcloud.kr/api/15071311/v1/uddi:b3803d43-ffe3-4d17-9024-fd6cfa37c284?page=1&perPage=10&serviceKey=[서비스키]" -H  "accept: application/json" -H  "Authorization: [인증키]"

 

이렇게 데이터를 출력하니 이렇게 한줄로 나와 한눈에 알아보기 불편했다.

{"currentCount":10,"data":[{"10시00분":"26.6","10시30분":"23.4","11시00분":"22.4","11시30분":"22.1","12시00분":"21.5","12시30분":"27.2","13시00분":"21.2","13시30분":"24.1","14시00분":"21.7","14시30분":"18.7","15시00분":"18.5","15시30분":"18.4","16시00분":"16.4","16시30분":"17.7","17시00분":"16.7","17시30분":"24.1","18시00분":"30.8","18시30분":"28.7","19시00분":"20.0","19시30분":"15.1","20시00분":"11.1","20시30분":"12.0","21시00분":"12.5","21시30분":"10.1","22시00분":"10.4","22시30분":"16.4","23시00분":"7.8","23시30분":"6.1","5시30분":"6.2","6시00분":"14.6","6시30분":"13.4","7시00분":"26.8","7시30분":"43.3","8시00분":"53.6","8시30분":"70.9","9시00분":"40.4","9시30분":"38.0","구분":"상선","역명":"서울역","역번호":150,"연번":1,"조사일자":"평일","호선":1},{"10시00분":"13.9","10시30분":"15.2","11시00분":"14.6","11시30분":"14.2","12시00분":"17.6","12시30분":"19.6","13시00분":"20.3","13시30분":"20.5","14시00분":"25.4","14시30분":"22.0","15시00분":"30.1","15시30분":"24.4","16시00분":"33.8","16시30분":"36.7","17시00분":"43.8","17시30분":"49.7","18시00분":"84.0","18시30분":"65.1","19시00분":"37.5","19시30분":"26.5","20시00분":"25.5","20시30분":"26.4","21시00분":"26.3","21시30분":"21.1","22시00분":"32.1","22시30분":"20.3","23시00분":"12.6","23시30분":"10.3","5시30분":"9.1","6시00분":"8.6","6시30분":"9.3","7시00분":"15.2","7시30분":"29.3","8시00분":"27.7","8시30분":"19.0","9시00분":"18.5","9시30분":"15.1","구분":"하선","역명":"서울역","역번호":150,"연번":2,"조사일자":"평일","호선":1},{"10시00분":"20.2","10시30분":"21.9","11시00분":"20.8","11시30분":"20.0","12시00분":"21.7","12시30분":"24.4","13시00분":"21.7","13시30분":"23.7","14시00분":"21.5","14시30분":"20.7","15시00분":"20.3","15시30분":"19.3","16시00분":"18.0","16시30분":"19.4","17시00분":"18.7","17시30분":"26.5","18시00분":"41.5","18시30분":"35.6","19시00분":"24.1","19시30분":"17.4","20시00분":"13.7","20시30분":"14.5","21시00분":"15.8","21시30분":"12.1","22시00분":"14.5","22시30분":"18.3","23시00분":"11.7","23시30분":"11.7","5시30분":"5.4","6시00분":"10.1","6시30분":"13.0","7시00분":"20.8","7시30분":"32.0","8시00분":"40.6","8시30분":"50.9","9시00분":"30.8","9시30분":"35.8","구분":"상선","역명":"시청","역번호":151,"연번":3,"조사일자":"평일","호선":1},{"10시00분":"13.5","10시30분":"14.2","11시00분":"13.7","11시30분":"13.2","12시00분":"17.3","12시30분":"18.4","13시00분":"19.6","13시30분":"19.4","14시00분":"24.2","14시30분":"22.9","15시00분":"27.0","15시30분":"26.4","16시00분":"30.6","16시30분":"30.5","17시00분":"41.1","17시30분":"45.3","18시00분":"81.2","18시30분":"59.2","19시00분":"33.8","19시30분":"22.9","20시00분":"22.0","20시30분":"24.1","21시00분":"23.0","21시30분":"21.0","22시00분":"24.8","22시30분":"18.5","23시00분":"11.8","23시30분":"9.1","5시30분":"7.0","6시00분":"6.8","6시30분":"10.2","7시00분":"14.5","7시30분":"27.0","8시00분":"24.7","8시30분":"20.0","9시00분":"18.4","9시30분":"14.5","구분":"하선","역명":"시청","역번호":151,"연번":4,"조사일자":"평일","호선":1},{"10시00분":"17.0","10시30분":"18.4","11시00분":"19.4","11시30분":"16.9","12시00분":"21.2","12시30분":"23.2","13시00분":"21.0","13시30분":"22.8","14시00분":"23.8","14시30분":"21.0","15시00분":"23.7","15시30분":"22.3","16시00분":"20.6","16시30분":"21.0","17시00분":"24.1","17시30분":"29.1","18시00분":"54.5","18시30분":"42.0","19시00분":"28.8","19시30분":"20.2","20시00분":"19.1","20시30분":"18.7","21시00분":"22.2","21시30분":"16.1","22시00분":"21.8","22시30분":"25.1","23시00분":"16.3","23시30분":"14.8","5시30분":"5.2","6시00분":"10.8","6시30분":"9.3","7시00분":"13.6","7시30분":"19.6","8시00분":"25.5","8시30분":"26.5","9시00분":"19.2","9시30분":"26.2","구분":"상선","역명":"종각","역번호":152,"연번":5,"조사일자":"평일","호선":1},{"10시00분":"14.9","10시30분":"15.6","11시00분":"15.0","11시30분":"14.4","12시00분":"16.5","12시30분":"19.9","13시00분":"19.2","13시30분":"20.5","14시00분":"25.9","14시30분":"20.0","15시00분":"29.0","15시30분":"21.0","16시00분":"30.6","16시30분":"26.0","17시00분":"37.8","17시30분":"38.3","18시00분":"60.2","18시30분":"44.2","19시00분":"22.1","19시30분":"21.2","20시00분":"17.6","20시30분":"19.2","21시00분":"18.2","21시30분":"17.0","22시00분":"21.1","22시30분":"15.1","23시00분":"10.7","23시30분":"7.1","5시30분":"7.8","6시00분":"7.4","6시30분":"10.9","7시00분":"18.7","7시30분":"29.7","8시00분":"37.8","8시30분":"31.3","9시00분":"24.1","9시30분":"18.5","구분":"하선","역명":"종각","역번호":152,"연번":6,"조사일자":"평일","호선":1},{"10시00분":"19.7","10시30분":"21.4","11시00분":"16.6","11시30분":"18.0","12시00분":"22.7","12시30분":"25.0","13시00분":"27.6","13시30분":"21.0","14시00분":"25.7","14시30분":"24.6","15시00분":"26.7","15시30분":"25.5","16시00분":"22.8","16시30분":"25.6","17시00분":"26.5","17시30분":"32.3","18시00분":"57.5","18시30분":"51.2","19시00분":"29.6","19시30분":"22.2","20시00분":"21.0","20시30분":"18.9","21시00분":"26.1","21시30분":"18.3","22시00분":"22.8","22시30분":"29.0","23시00분":"18.2","23시30분":"16.6","5시30분":"4.8","6시00분":"9.8","6시30분":"9.0","7시00분":"12.9","7시30분":"20.4","8시00분":"30.8","8시30분":"25.5","9시00분":"18.9","9시30분":"23.6","구분":"상선","역명":"종로3가","역번호":153,"연번":7,"조사일자":"평일","호선":1},{"10시00분":"17.5","10시30분":"18.7","11시00분":"14.6","11시30분":"17.7","12시00분":"18.7","12시30분":"19.3","13시00분":"19.2","13시30분":"20.3","14시00분":"25.6","14시30분":"18.7","15시00분":"27.2","15시30분":"20.4","16시00분":"27.2","16시30분":"23.7","17시00분":"26.6","17시30분":"34.6","18시00분":"39.9","18시30분":"34.5","19시00분":"16.8","19시30분":"16.0","20시00분":"12.8","20시30분":"13.2","21시00분":"11.7","21시30분":"10.1","22시00분":"12.9","22시30분":"9.6","23시00분":"6.9","23시30분":"4.9","5시30분":"9.1","6시00분":"7.3","6시30분":"14.0","7시00분":"23.3","7시30분":"38.8","8시00분":"51.6","8시30분":"49.6","9시00분":"35.6","9시30분":"26.5","구분":"하선","역명":"종로3가","역번호":153,"연번":8,"조사일자":"평일","호선":1},{"10시00분":"18.7","10시30분":"15.4","11시00분":"14.2","11시30분":"15.3","12시00분":"23.7","12시30분":"18.7","13시00분":"25.8","13시30분":"17.7","14시00분":"25.3","14시30분":"24.2","15시00분":"30.1","15시30분":"22.6","16시00분":"23.3","16시30분":"26.9","17시00분":"25.2","17시30분":"35.6","18시00분":"60.4","18시30분":"54.6","19시00분":"34.3","19시30분":"22.8","20시00분":"21.5","20시30분":"21.9","21시00분":"27.8","21시30분":"22.4","22시00분":"20.8","22시30분":"29.8","23시00분":"18.7","23시30분":"16.7","5시30분":"4.3","6시00분":"7.9","6시30분":"7.4","7시00분":"9.9","7시30분":"15.6","8시00분":"22.2","8시30분":"16.7","9시00분":"16.5","9시30분":"15.8","구분":"상선","역명":"종로5가","역번호":154,"연번":9,"조사일자":"평일","호선":1},{"10시00분":"20.9","10시30분":"24.3","11시00분":"19.0","11시30분":"17.3","12시00분":"24.8","12시30분":"25.9","13시00분":"18.1","13시30분":"23.0","14시00분":"25.0","14시30분":"24.4","15시00분":"25.7","15시30분":"24.1","16시00분":"24.9","16시30분":"28.3","17시00분":"26.9","17시30분":"34.6","18시00분":"40.5","18시30분":"27.4","19시00분":"18.3","19시30분":"13.8","20시00분":"12.2","20시30분":"12.1","21시00분":"10.8","21시30분":"9.6","22시00분":"11.1","22시30분":"7.9","23시00분":"6.7","23시30분":"4.3","5시30분":"10.8","6시00분":"7.9","6시30분":"16.4","7시00분":"28.4","7시30분":"40.7","8시00분":"58.7","8시30분":"50.7","9시00분":"42.7","9시30분":"28.5","구분":"하선","역명":"종로5가","역번호":154,"연번":10,"조사일자":"평일","호선":1}],"matchCount":1704,"page":1,"perPage":10,"totalCount":1704}

 

 

그래서 Python 으로 스크립트를 만들어 json 형태의 데이터를 확인할 수 있었다.

# get-subway-data.py 

import requests
import json
from pprint import pprint

url = 'https://api.odcloud.kr/api/15071311/v1/uddi:b3803d43-ffe3-4d17-9024-fd6cfa37c284'

params = {
    'serviceKey' : [서비스키 입력], 
    'type' : 'json',
    'perPage' : '10', 
    'page' : 1
    }

response = requests.get(url, params=params)

data = json.loads(response.text)

pprint(data)

 

스크립트 실행 결과는 다음과 같이 확인할 수 있었다.

$ python3 get-subway-data.py 
{'currentCount': 10,
 'data': [{'10시00분': '26.6',
           '10시30분': '23.4',
           '11시00분': '22.4',
           '11시30분': '22.1',
           '12시00분': '21.5',
           '12시30분': '27.2',
           '13시00분': '21.2',
           '13시30분': '24.1',
           '14시00분': '21.7',
           '14시30분': '18.7',
           '15시00분': '18.5',
           '15시30분': '18.4',
           '16시00분': '16.4',
           '16시30분': '17.7',
           '17시00분': '16.7',
           '17시30분': '24.1',
           '18시00분': '30.8',
           '18시30분': '28.7',
           '19시00분': '20.0',
           '19시30분': '15.1',
           '20시00분': '11.1',
           '20시30분': '12.0',
           '21시00분': '12.5',
           '21시30분': '10.1',
           '22시00분': '10.4',
           '22시30분': '16.4',
           '23시00분': '7.8',
           '23시30분': '6.1',
           '5시30분': '6.2',
           '6시00분': '14.6',
           '6시30분': '13.4',
           '7시00분': '26.8',
           '7시30분': '43.3',
           '8시00분': '53.6',
           '8시30분': '70.9',
           '9시00분': '40.4',
           '9시30분': '38.0',
           '구분': '상선',
           '역명': '서울역',
           '역번호': 150,
           '연번': 1,
           '조사일자': '평일',
           '호선': 1},
           (...snip...)

 

Airflow DAG 생성 후 테스트

API 를 통해 데이터를 가져오는 과정을 airflow DAG 를 만들어 가져오는 간단한 테스트를 한번 진행해봤다.

 

내가 작성한 DAG 는 다음과 같다. 테스트로 확인할 겸 만든 DAG 파일이라 다소 간단하게 만들어봤다.
BashOperator 를 통해 bash 명령어를 실행해 API 를 호출하는 방법으로 데이터를 가져와 저장할 수 있었다.

import json
import pathlib

import requests
import requests.exceptions as requests_exceptions

import airflow
from airflow import DAG
from airflow.operators.bash import BashOperator


dag = DAG(
    dag_id="collect_subway_congestion",
    start_date=airflow.utils.dates.days_ago(1),
    schedule_interval=None,
    tags=["subway"],
)

collect_subway_congestion = BashOperator(
    task_id="collect-subway-congestion",
    bash_command='curl -o /Users/jaynam/workspace/airflow/data/subway_data_{{ds_nodash}}.json \
        -X GET "https://api.odcloud.kr/api/15071311/v1/uddi:b3803d43-ffe3-4d17-9024-fd6cfa37c284?page=1&perPage=2000&serviceKey=[서비스키]" \
        -H  "accept: application/json" \
        -H  "Authorization: [인증키]"',
    dag=dag,
    # env: Optional[Dict[str, str]] = None,
    # output_encoding: str = 'utf-8',
    # skip_exit_code: int = 99,
)


collect_subway_congestion

 

 

airflow 에서 만들어진 DAG 를 확인할 수 있었다.

DAG 를 ON 으로 변경한 후 실행해보았다.

작업이 정상적으로 완료되었고 나는 로컬에 데이터를 저장했기 때문에 잘 저장이 되었는지 확인해봤다.

json 파일이 정상적으로 생성된 것을 확인할 수 있었고 curl 로 API 를 호출해서 데이터를 가져왔기 때문에 한줄로 모든 데이터가 가져와진 것을 확인할 수 있었다.

 

다음 과정

이렇게 공공데이터포털에서 데이터를 가져오는 과정을 해보고 또 airflow DAG 를 생성해서 데이터를 저장하는 테스트도 진행해보았다.
다음 과정으로 공공데이터포털에서 가져온 json 형태의 데이터를 어떻게 저장할 것인가에 대해서 생각이 필요해보였다. 데이터를 설계하는 과정이라고 해야할까? 데이터를 어떻게 구분해서 저장하고 활용할 수 있는지에 대한 고민이 많이 되었다. 어떻게 저장할지에 대한 고민이 끝나면 저장될 테이블을 생성해서 데이터를 가공 후에 insert 하면 될 것 같다.

 

일단은 가져온 데이터를 어떻게 구분해서 저장할지부터 고민해보고 테이블을 만들어서 저장해봐야겠다.

728x90
반응형
복사했습니다!