일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- cluster
- 주식
- MQTT
- 홈네트워크
- 나스닥
- 라즈베리파이
- Python
- Home Assistant
- raspberry pi
- 미국주식
- 국내주식
- Apple
- 해외주식
- 현대통신
- homebridge
- esp32
- SK텔레콤
- matter
- RS-485
- 파이썬
- 애플
- 빅데이터분석기사
- 힐스테이트 광교산
- 공모주
- Espressif
- 월패드
- Bestin
- 배당
- ConnectedHomeIP
- 매터
- Today
- Total
YOGYUI
공공데이터포털::공휴일 데이터 조회 (REST API) 본문
회사에서 사원별 공수(Man Hour) 관리 프로그램을 하나 만들었는데, 공휴일에는 입력이 안되게 만드는 기능이 필요하게 됐다
파이썬 써드파티 라이브러리 종류도 몇 개 있어 찾아봤는데, 중국의 국경일을 기반으로 한국의 실정에 맞게 변환해야 하는 경우가 대부분이라 번거로울 뿐만 아니라 대통령 선거같은 이벤트나 임시공휴일은 유저가 따로 입력해야 하는 불편함이 있다
확실한 건 웹크롤링인데, (ex: 주식시장 개장일) 공공데이터포털에서도 API 몇 개가 공개되어 있어서 그 중 한개를 사용하도록 했다
1. 공공데이터포털 API 활용신청
데이터 타이틀은 "특일 정보", URL은 아래 링크 참고
https://www.data.go.kr/tcs/dss/selectApiDataDetailView.do?publicDataPk=15012690
한국천문연구원(?!)에서 제공하는 데이터로, 국경일 및 공휴일 뿐만 아니라 24절기 등 유용한 정보를 긁어올 수 있다
바로 API 활용신청 (신청법은 링크 참고)하고 인증키를 받아오자
(인증안된다는 문의가 너무 많아서 그런가, URL 인코딩된 인증키랑 일반 인증키 둘 다 기재해뒀다 ㅋㅋ)
서비스 URL: http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/{서비스오퍼레이션}
필요한 정보에 따라 URL 뒤에 붙여야하는 문자열(서비스오퍼레이션)이 다르다
서비스 종류 | 서비스 오퍼레이션명 |
국경일 정보조회 | getHoliDeInfo |
공휴일 정보조회 | getRestDeInfo |
기념일 정보조회 | getAnniversaryInfo |
24절기 정보조회 | get24DivisionsInfo |
잡절 정보조회 | getSundryDayInfo |
호출 파라미터는 다음과 같다
필요한 정보는 모두 얻었으니 바로 코딩해보자
2. 테스트 코드
import requests
from urllib import parse
url = "http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/"
api_key_utf8 = "Your API Key from data.go.kr"
api_key_decode = parse.unquote(api_key_utf8)
url_holiday = url + "getRestDeInfo"
params = {
"ServiceKey": api_key_decode,
"solYear": 2021,
"numOfRows": 100
}
response = requests.get(url_holiday, params=params)
2021년 전체의 공휴일(getRestDeInfo)을 요청해봤다
공휴일이 100일을 넘는 경우는 없을테니 대충 한 페이지에 표시할 아이템 수(numOfRows)는 100으로 설정
In [1]: print(response.text)
Out[1]:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<header>
<resultCode>00</resultCode>
<resultMsg>NORMAL SERVICE.</resultMsg>
</header>
<body>
<items>
<item>
<dateKind>01</dateKind>
<dateName>1월1일</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210101</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>설날</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210211</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>설날</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210212</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>설날</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210213</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>삼일절</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210301</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>어린이날</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210505</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>부처님오신날</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210519</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>현충일</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210606</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>광복절</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210815</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>추석</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210920</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>추석</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210921</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>추석</dateName>
<isHoliday>Y</isHoliday>
<locdate>20210922</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>개천절</dateName>
<isHoliday>Y</isHoliday>
<locdate>20211003</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>한글날</dateName>
<isHoliday>Y</isHoliday>
<locdate>20211009</locdate>
<seq>1</seq>
</item>
<item>
<dateKind>01</dateKind>
<dateName>기독탄신일</dateName>
<isHoliday>Y</isHoliday>
<locdate>20211225</locdate>
<seq>1</seq>
</item>
</items>
<numOfRows>100</numOfRows>
<pageNo>1</pageNo>
<totalCount>15</totalCount>
</body>
</response>
총 아이템 수는 15개이고, 3일씩 연속되는 설날과 추석을 고려하면 11개의 공휴일이 있는 것으로 나온다
웹에서 검색한 다른 데이터와도 일치한다
아이템의 태그들에 대한 설명은 다음과 같다
dateKind | 종류 01: 국경일 (ex: 어린이날, 광복절, 개천절) 02: 기념일 (ex: 의병의 날, 정보보호의 날, 4/19 혁명 기념일) 03: 24절기 (ex: 청명, 경칩, 하지) 04: 잡절 (ex: 단오, 한식) |
dateName | 명칭 |
isHoliday | 공공기관 휴일여부 |
locdate | 날짜 |
seq | 순번 |
12월 25일을 크리스마스나 성탄절이 아니라 '기독탄신일'이라고 부르는게 인상적이다
(석가탄신일은 또 부처님오신날이라고 하네? ㅋㅋ)
3. Pandas DataFrame
공휴일을 크롤링하는 구문을 함수화해보자 (반환은 pandas DataFrame으로)
import requests
from urllib import parse
import pandas as pd
from bs4 import BeautifulSoup
from datetime import datetime
def getHoliday(year: int) -> pd.DataFrame:
url = "http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo"
api_key_utf8 = "Your API Key from data.go.kr"
api_key_decode = parse.unquote(api_key_utf8)
params = {
"ServiceKey": api_key_decode,
"solYear": year,
"numOfRows": 100
}
response = requests.get(url, params=params)
xml = BeautifulSoup(response.text, "lxml")
items = xml.find('items')
item_list = []
for item in items:
item_dict = {
"이름": item.find("datename").text.strip(),
"날짜": datetime.strptime(item.find("locdate").text.strip(), '%Y%m%d')
}
item_list.append(item_dict)
return pd.DataFrame(item_list)
In [2]: print(getHoliday(2021))
Out[2]:
이름 날짜
0 1월1일 2021-01-01
1 설날 2021-02-11
2 설날 2021-02-12
3 설날 2021-02-13
4 삼일절 2021-03-01
5 어린이날 2021-05-05
6 부처님오신날 2021-05-19
7 현충일 2021-06-06
8 광복절 2021-08-15
9 추석 2021-09-20
10 추석 2021-09-21
11 추석 2021-09-22
12 개천절 2021-10-03
13 한글날 2021-10-09
14 기독탄신일 2021-12-25
테스트삼아 2022년 공휴일도 한번 불러와봤다
In [3]: print(getHoliday(2022))
Out[3]:
이름 날짜
0 1월1일 2022-01-01
1 설날 2022-01-31
2 설날 2022-02-01
3 설날 2022-02-02
4 삼일절 2022-03-01
5 대통령선거일 2022-03-09
6 어린이날 2022-05-05
7 부처님오신날 2022-05-08
8 전국동시지방선거 2022-06-01
9 현충일 2022-06-06
10 광복절 2022-08-15
11 추석 2022-09-09
12 추석 2022-09-10
13 추석 2022-09-11
14 대체공휴일 2022-09-12
15 개천절 2022-10-03
16 한글날 2022-10-09
17 기독탄신일 2022-12-25
선거일까지 잘 반영이 된다!
데이터프레임에 요일 정보까지 함께 포함하고 싶으면 다음과 같이 추가해주면 된다
(datetime weekday() 사용)
def getHoliday(year: int) -> pd.DataFrame:
url = "http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo"
api_key_utf8 = "Your API Key from data.go.kr"
api_key_decode = parse.unquote(api_key_utf8)
params = {
"ServiceKey": api_key_decode,
"solYear": year,
"numOfRows": 100
}
temp = ["월", "화", "수", "목", "금", "토", "일"]
response = requests.get(url, params=params)
xml = BeautifulSoup(response.text, "lxml")
items = xml.find('items')
item_list = []
for item in items:
dt = datetime.strptime(item.find("locdate").text.strip(), '%Y%m%d')
item_dict = {
"이름": item.find("datename").text.strip(),
"날짜": dt,
"요일": temp[dt.weekday()]
}
item_list.append(item_dict)
return pd.DataFrame(item_list)
In [4]: print(getHoliday(2021))
Out[4]:
이름 날짜 요일
0 1월1일 2021-01-01 금
1 설날 2021-02-11 목
2 설날 2021-02-12 금
3 설날 2021-02-13 토
4 삼일절 2021-03-01 월
5 어린이날 2021-05-05 수
6 부처님오신날 2021-05-19 수
7 현충일 2021-06-06 일
8 광복절 2021-08-15 일
9 추석 2021-09-20 월
10 추석 2021-09-21 화
11 추석 2021-09-22 수
12 개천절 2021-10-03 일
13 한글날 2021-10-09 토
14 기독탄신일 2021-12-25 토
두고두고 유용하게 잘 써먹을 수 있을 것 같다
끝~!
'Data Analysis > Data Engineering' 카테고리의 다른 글
금융감독원::OPENDART 전자공시 Open API 사용하기 (17) | 2021.09.18 |
---|---|
공공데이터포털::전기차 충전소 운영정보 조회 (REST API) (2) | 2021.06.25 |
Python::folium - 빅데이터분석기사 필기시험 고사장 위치 지도시각화 (0) | 2021.02.26 |
공공데이터포털::코로나19 감염현황 데이터 조회 (REST API) (0) | 2021.02.22 |
Python::BeautifulSoup - 동행복권 연금복권720+ 당첨번호 크롤링 (0) | 2021.02.21 |