[Python]政府資料開放平臺Open Data資料取得

串接行政機關辦公日曆

Posted by 許仕杰 on Tuesday, June 15, 2021

TOC

前提

在上一篇文章[Odoo]透過系統排程進行自動化管理中,我們透過Odoo Scheduled Actions+LINE Notify達到自動化的提醒功能,但若遇到特殊休假日時,系統還是會自動執行排程,因此本章節來讓程式能自行的判斷遇到休假日時就不進行提醒的部分!

為了降低維護休假日的Loading,這裡直接串接政府提供的Open Data!


政府資料開放平臺(Open Data)

「政府資料開放」(Open Data)為各機關於職權範圍內取得或做成,且依法得公開之各類電子資料,包含文字、數據、圖片、影像、聲音、詮釋資料(metadata)等,以開放格式於網路公開,提供個人、學校、團體、企業或政府機關等使用者,依其需求連結下載及利用。

出處:https://data.gov.tw/faqs/1463

首先在眾多的資料集中,選了一個自己比較喜歡的Open Data『臺北市政府行政機關辦公日曆表』,其主要原因有以下兩點:

  1. 提供JSON格式:以程式處理的角度,後續的資料剖析較為容易。
  2. 提供所有年度資料(2013~2021):跨到下一個年度時,需要更新連結的機率較低。
臺北市政府行政機關辦公日曆表檢視資料

此時依序點擊 資料資源下載網址>檢視資料>多元格式參考資料>JSON>右鍵 複製連結 (後面code會用到) ,並且可以測試下載的JSON檔案格式內容是否為自己所需要的內容。(如下)

# 下方為下載JSON內容
[
   {
      "date":"2013/1/1",
      "name":"中華民國開國紀念日",
      "isHoliday":"是",
      "holidayCategory":"放假之紀念日及節日",
      "description":"全國各機關學校放假一日。"
   },
   {
      "date":"2013/1/5",
      "name":"",
      "isHoliday":"是",
      "holidayCategory":"星期六、星期日",
      "description":""
   },
   (略...)
   {
      "date":"2021/12/31",
      "name":"",
      "isHoliday":"是",
      "holidayCategory":"補假",
      "description":""
   }
]

使用urllib套件取得網路資源

這裡採取urllib.request模組並搭配urlopen()函數,將上面的JSON的 複製連結 內容放到code當中,這裡並且搭配 import json將str型別的資料轉成dict。

import urllib.request as req
import json
# 串接 政府行政機關辦公日曆表
def open_data_api(self):
    # 臺北市政府行政機關辦公日曆表 (來源: https://data.gov.tw/dataset/137991 )
    url = 'https://quality.data.gov.tw/dq_download_json.php?nid=137991&md5_url=94280f3f5a15c25fe38148b8b100c346'

    with req.urlopen(url) as res:
        input_data = json.loads(res.read().decode())

接著將拿到的資料,進行一系列的加工處理。

  1. 依日期由大至小排序(本次不處理,但後續方便將年度Data寫入Database)
  2. 檢查當日是否為休假日

執行成效

LINE執行效果

最後附上完整的程式碼

# 串接 政府行政機關辦公日曆表
def open_data_api(self):
    # 臺北市政府行政機關辦公日曆表 (來源: https://data.gov.tw/dataset/137991 )
    url = 'https://quality.data.gov.tw/dq_download_json.php?nid=137991&md5_url=94280f3f5a15c25fe38148b8b100c346'

    with req.urlopen(url) as res:
        input_data = json.loads(res.read().decode())
    # input_data.sort(key=lambda x: datetime.strptime(x['date'], '%Y/%m/%d'), reverse=True)  # 排序[date]由大到小

    # 當天是否為國定假日
    now_time = datetime.today()
    # now_time = datetime.strptime('2021/1/1', '%Y/%m/%d')  # 測試日期用
    filter_data = [x for x in input_data if datetime.strptime(x['date'], '%Y/%m/%d') == now_time]

    if (len(filter_data) > 0):
        if (filter_data[0]['isHoliday'] == '是'):
            return False  #休假日/補假
    return True           #上班日/補班

Reference