Python 網路爬蟲 一般天氣預報-今明36小時天氣預報--python TKinter
{
"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()
沒有留言:
張貼留言