2025年8月11日 星期一

Python 網路爬蟲 一般天氣預報-今明36小時天氣預報--python TKinter

Python 網路爬蟲   一般天氣預報-今明36小時天氣預報--python TKinter    



https://data.gov.tw/datasets/search?p=1&size=10&s=_score_desc&rft=%E4%BB%8A%E6%98%8E36%E5%B0%8F%E6%99%82%E5%A4%A9%E6%B0%A3%E9%A0%90%E5%A0%B1

主要欄位說明
*粗體欄位為資料標準欄位
locationName(地點)、
elementName(預報因子)、
startTime(起始時間)、
endTime(結束時間)、
parameter(預報內容)
資料資源下載網址
  • 一般天氣預報-今明36小時天氣預報
  • 今明36小時天氣預報API
  • 今明36小時天氣預報

{

 "cwaopendata": {

  "@xmlns": "urn:cwa:gov:tw:cwacommon:0.1",

  "identifier": "05bc5fd4-9289-8042-7d0e-9a51381fc990",

  "sender": "weather@cwa.gov.tw",

  "sent": "2025-08-11T11:15:45+08:00",

  "status": "Actual",

  "msgType": "Issue",

  "source": "MFC",

  "dataid": "C0032-001",

  "scope": "Public",

  "dataset": {

   "datasetInfo": {

    "datasetDescription": "三十六小時天氣預報",

    "issueTime": "2025-08-11T11:00:00+08:00",

    "update": "2025-08-11T11:15:45+08:00"

   },

   "location": [

    {

     "locationName": "臺北市",

     "weatherElement": [

      {

       "elementName": "Wx",

       "time": [

        {

         "startTime": "2025-08-11T12:00:00+08:00",

         "endTime": "2025-08-11T18:00:00+08:00",

         "parameter": {

          "parameterName": "多雲午後短暫雷陣雨",

          "parameterValue": "22"

         }

        },

        {

         "startTime": "2025-08-11T18:00:00+08:00",

         "endTime": "2025-08-12T06:00:00+08:00",

         "parameter": {

          "parameterName": "多雲",

          "parameterValue": "4"

         }

        },

        {

         "startTime": "2025-08-12T06:00:00+08:00",

         "endTime": "2025-08-12T18:00:00+08:00",

         "parameter": {

          "parameterName": "多雲午後短暫雷陣雨",

          "parameterValue": "22"

         }

        }

       ]

      },

      {

       "elementName": "MaxT",

       "time": [

        {

         "startTime": "2025-08-11T12:00:00+08:00",

         "endTime": "2025-08-11T18:00:00+08:00",

         "parameter": {

          "parameterName": "35",

          "parameterUnit": "C"

         }

        },

        {

         "startTime": "2025-08-11T18:00:00+08:00",

         "endTime": "2025-08-12T06:00:00+08:00",

         "parameter": {

          "parameterName": "31",

          "parameterUnit": "C"

         }

        },

        {

         "startTime": "2025-08-12T06:00:00+08:00",

         "endTime": "2025-08-12T18:00:00+08:00",

         "parameter": {

          "parameterName": "35",

          "parameterUnit": "C"

         }

        }

       ]

      },

      {

       "elementName": "MinT",

       "time": [

        {

         "startTime": "2025-08-11T12:00:00+08:00",

         "endTime": "2025-08-11T18:00:00+08:00",

         "parameter": {

          "parameterName": "31",

          "parameterUnit": "C"

         }

        },

        {

         "startTime": "2025-08-11T18:00:00+08:00",

         "endTime": "2025-08-12T06:00:00+08:00",

         "parameter": {

          "parameterName": "27",

          "parameterUnit": "C"

         }

        },

        {

         "startTime": "2025-08-12T06:00:00+08:00",

         "endTime": "2025-08-12T18:00:00+08:00",

         "parameter": {

          "parameterName": "27",

          "parameterUnit": "C"

         }

        }

       ]

      },

      {

       "elementName": "CI",

       "time": [

        {

         "startTime": "2025-08-11T12:00:00+08:00",

         "endTime": "2025-08-11T18:00:00+08:00",

         "parameter": {

          "parameterName": "悶熱至易中暑"

         }

        },

        {

         "startTime": "2025-08-11T18:00:00+08:00",

         "endTime": "2025-08-12T06:00:00+08:00",

         "parameter": {

          "parameterName": "舒適至悶熱"

         }

        },

        {

         "startTime": "2025-08-12T06:00:00+08:00",

         "endTime": "2025-08-12T18:00:00+08:00",

         "parameter": {

          "parameterName": "舒適至易中暑"

         }

        }

       ]

      },

      {

       "elementName": "PoP",

       "time": [

        {

         "startTime": "2025-08-11T12:00:00+08:00",

         "endTime": "2025-08-11T18:00:00+08:00",

         "parameter": {

          "parameterName": "80",

          "parameterUnit": "百分比"

         }

        },

        {

         "startTime": "2025-08-11T18:00:00+08:00",

         "endTime": "2025-08-12T06:00:00+08:00",

         "parameter": {

          "parameterName": "20",

          "parameterUnit": "百分比"

         }

        },

        {

         "startTime": "2025-08-12T06:00:00+08:00",

         "endTime": "2025-08-12T18:00:00+08:00",

         "parameter": {

          "parameterName": "40",

          "parameterUnit": "百分比"

         }

        }

       ]

      }

     ]

    },


<<Python TKinter>>

import tkinter as tk

from tkinter import ttk, messagebox

import requests


# API 網址,此為中央氣象署提供的範例授權碼,實際使用需申請

URL = "https://opendata.cwa.gov.tw/fileapi/v1/opendataapi/F-C0032-001?Authorization=rdec-key-123-45678-011121314&format=JSON"


def fetch_weather_data():

    """從中央氣象署 API 取得天氣預報資料"""

    try:

        response = requests.get(URL)

        response.raise_for_status()  # 如果請求失敗,引發 HTTPError

        data = response.json()

        

        # 解析 JSON 資料,提取我們需要的欄位

        weather_data = []

        locations = data['cwaopendata']['dataset']['location']

        

        for loc in locations:

            location_name = loc['locationName']

            

            # 取得各項預報元素

            elements = {elem['elementName']: elem['time'][0]['parameter'] for elem in loc['weatherElement']}

            

            # 從元素字典中提取數值,並處理可能不存在的鍵

            wx = elements.get('Wx', {}).get('parameterName', 'N/A')

            min_t = elements.get('MinT', {}).get('parameterName', 'N/A')

            max_t = elements.get('MaxT', {}).get('parameterName', 'N/A')

            ci = elements.get('CI', {}).get('parameterName', 'N/A')

            pop = elements.get('PoP', {}).get('parameterName', 'N/A')

            

            weather_data.append((location_name, wx, min_t, max_t, ci, pop))

            

        return weather_data

    except requests.exceptions.RequestException as e:

        messagebox.showerror("錯誤", f"無法連線到 API,請檢查網路連線或 API 狀態。\n錯誤訊息: {e}")

        return []


def update_weather_display(event=None):

    """根據篩選條件更新 Treeview 顯示"""

    # 清空 Treeview 中的所有舊資料

    for item in tree.get_children():

        tree.delete(item)


    selected_city = city_combobox.get()

    

    # 從全域變數中取得所有天氣資料

    all_weather_data = fetch_weather_data()

    

    if all_weather_data:

        # 取得所有縣市名稱,用於下拉式選單

        city_names = sorted(list(set(item[0] for item in all_weather_data)))

        city_combobox['values'] = ['所有縣市'] + city_names

        

        # 根據選擇的縣市進行篩選

        if selected_city == "所有縣市" or selected_city == "":

            filtered_data = all_weather_data

        else:

            filtered_data = [item for item in all_weather_data if item[0] == selected_city]


        # 將篩選後的資料插入到 Treeview 中

        for row in filtered_data:

            tree.insert("", "end", values=row)


def create_widgets():

    """建立並配置 GUI 元件"""

    # 建立篩選框架

    filter_frame = ttk.Frame(root, padding="10")

    filter_frame.pack(fill="x")

    

    ttk.Label(filter_frame, text="選擇縣市:").pack(side="left", padx=(0, 5))

    

    global city_combobox

    city_combobox = ttk.Combobox(filter_frame, state="readonly", width=20)

    city_combobox.pack(side="left")

    city_combobox.bind("<<ComboboxSelected>>", update_weather_display)

    

    refresh_button = ttk.Button(filter_frame, text="重新整理", command=update_weather_display)

    refresh_button.pack(side="left", padx=10)


    # 建立 Treeview 框架

    tree_frame = ttk.Frame(root, padding="10")

    tree_frame.pack(fill="both", expand=True)


    columns = ('city', 'wx', 'min_t', 'max_t', 'ci', 'pop')

    global tree

    tree = ttk.Treeview(tree_frame, columns=columns, show='headings')

    

    tree.heading('city', text='縣市')

    tree.heading('wx', text='天氣現象')

    tree.heading('min_t', text='最低溫 (°C)')

    tree.heading('max_t', text='最高溫 (°C)')

    tree.heading('ci', text='舒適度')

    tree.heading('pop', text='降雨機率 (%)')

    

    tree.column('city', width=100)

    tree.column('wx', width=100)

    tree.column('min_t', width=80)

    tree.column('max_t', width=80)

    tree.column('ci', width=80)

    tree.column('pop', width=80)

    

    # 新增捲軸

    scrollbar = ttk.Scrollbar(tree_frame, orient=tk.VERTICAL, command=tree.yview)

    tree.configure(yscrollcommand=scrollbar.set)

    scrollbar.pack(side="right", fill="y")

    tree.pack(fill="both", expand=True)


# 建立主視窗

root = tk.Tk()

root.title("今明36小時天氣預報")

root.geometry("800x600")


# 建立 GUI 元件

create_widgets()


# 程式啟動時自動載入資料並更新顯示

update_weather_display()


# 啟動 Tkinter 事件迴圈

root.mainloop()


沒有留言:

張貼留言

ESP32 (ESP-IDF in VS Code) MFRC522 + MQTT + PYTHON TKinter +SQLite

 ESP32 (ESP-IDF in VS Code) MFRC522 + MQTT + PYTHON TKinter +SQLite  ESP32 VS Code 程式 ; PlatformIO Project Configuration File ; ;   Build op...