[Python 데이터분석] 공공데이터포털::공휴일 데이터 조회 (REST API)

공공데이터포털::공휴일 데이터 조회 (REST API)

회사에서 사원별 공수(Man Hour) 관리 프로그램을 하나 만들었는데, 공휴일에는 입력이 안되게 만드는 기능이 필요하게 됐다

 

파이썬 써드파티 라이브러리 종류도 몇 개 있어 찾아봤는데, 중국의 국경일을 기반으로 한국의 실정에 맞게 변환해야 하는 경우가 대부분이라 번거로울 뿐만 아니라 대통령 선거같은 이벤트나 임시공휴일은 유저가 따로 입력해야 하는 불편함이 있다

 

확실한 건 웹크롤링인데, (ex: 주식시장 개장일) 공공데이터포털에서도 API 몇 개가 공개되어 있어서 그 중 한개를 사용하도록 했다

 

1. 공공데이터포털 API 활용신청

데이터 타이틀은 "특일 정보", URL은 아래 링크 참고

www.data.go.kr/iim/api/selectAPIAcountView.do

 

 

메타데이터 정보

 

한국천문연구원(?!)에서 제공하는 데이터로, 국경일 및 공휴일 뿐만 아니라 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개의 공휴일이 있는 것으로 나온다

웹에서 검색한 다른 데이터와도 일치한다

 

출처: https://publicholidays.co.kr/ko/2021-dates/

 

아이템의 태그들에 대한 설명은 다음과 같다

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   토

두고두고 유용하게 잘 써먹을 수 있을 것 같다

끝~!

 

[출처] https://yogyui.tistory.com/entry/%EA%B3%B5%EA%B3%B5%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%8F%AC%ED%84%B8%EA%B3%B5%ED%9C%B4%EC%9D%BC-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A1%B0%ED%9A%8C-REST-API

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
369 [Python 데이터분석] [pandas] 공공데이터(csv) 활용시 한글 깨짐 현상 해결 file 졸리운_곰 2021.09.30 3
» [Python 데이터분석] 공공데이터포털::공휴일 데이터 조회 (REST API) file 졸리운_곰 2021.09.30 0
367 [Python 데이터 분석] pandas의 to_csv()를 사용해서 csv 파일로 저장하기(save 하기) 졸리운_곰 2021.09.29 0
366 [Python 데이터 분석] 데이터 과학을 단순하게 만드는 3가지 Python 패키지 file 졸리운_곰 2021.09.24 4
365 [Python][Dash] DASH PLOTLY 설치부터 튜토리얼까지 졸리운_곰 2021.09.11 2
364 python - 국가공휴일 데이터 가져오기 (data.go.kr) file 졸리운_곰 2021.09.05 5
363 [python][web] Separate Front-end from Back-end with Flask+AJAX file 졸리운_곰 2021.08.13 4
362 [python][파이썬 조건문(if-elif-else)] 졸리운_곰 2021.07.24 9
361 [python] 파이썬 for 문 졸리운_곰 2021.07.24 7
360 [python][파이썬 기초] 48 파이썬으로 파일 만들기 졸리운_곰 2021.07.24 12
359 [Python] UnicodeEncodeError: 'ascii' codec can't encode file 졸리운_곰 2021.07.24 2
358 [python] *args 와 **kwargs 사용하기 - 슬기로운 파이썬 트릭 中 file 졸리운_곰 2021.07.24 5
357 [python] *args 와 **kwargs 졸리운_곰 2021.07.24 7
356 [python] 파이썬 f-string (파이썬 스트링 앞에 f') file 졸리운_곰 2021.07.17 10
355 [Python] 파이썬으로 복리 계산하기 file 졸리운_곰 2021.07.17 8
354 [python, 파이썬] 연습 문제: 복리 이자 계산 졸리운_곰 2021.07.17 65
353 python - 읽은 후 kafka 메시지를 삭제하는 방법 졸리운_곰 2021.07.13 5
352 [scrapy] https://pypi.org/project/scrapy-save-as-pdf/ 졸리운_곰 2021.07.03 34
351 Pipeline to Download PDF or Save page as PDF for scrapy item 졸리운_곰 2021.06.26 6
350 [python, 인터넷] [카프카] Python으로 Kafka에 전송(Producer)하고 가져오기(consumer) file 졸리운_곰 2021.06.19 8
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED