台灣銀行 牌告匯率--Python TKInter
import tkinter as tk
from tkinter import ttk, messagebox
import requests
from bs4 import BeautifulSoup
import datetime
def fetch_exchange_rates():
"""
從台灣銀行網站抓取即時匯率數據。
"""
url = "https://rate.bot.com.tw/xrt?Lang=zh-TW"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
} # 加上 User-Agent 模擬瀏覽器請求,避免被網站阻擋
try:
response = requests.get(url, headers=headers)
response.raise_for_status() # 檢查 HTTP 請求是否成功
soup = BeautifulSoup(response.text, 'html.parser')
# 找到匯率表格
exchange_table = soup.find('table', class_='table-bordered')
if not exchange_table:
messagebox.showerror("解析錯誤", "無法找到匯率表格。網站結構可能已改變。")
return None
rates_data = []
# 遍歷表格的每一行 (從第二行開始,因為第一行是表頭)
# 注意:使用 tbody 可以確保我們只處理數據行
for row in exchange_table.find('tbody').find_all('tr'):
cols = row.find_all('td')
if len(cols) >= 6: # 確保有足夠的欄位來包含所有匯率類型 (通常是 6 個 td)
currency_name = cols[0].find('div', class_='print_show').text.strip()
# 移除幣別名稱中的換行符和多餘空格
currency_name = currency_name.replace('\n', ' ').strip()
currency_name = ' '.join(currency_name.split()) # 將多個空格替換為單一空格
# 現金匯率
cash_buy_rate = cols[1].text.strip() # 現金買入
cash_sell_rate = cols[2].text.strip() # 現金賣出
# 即期匯率
spot_buy_rate = cols[3].text.strip() # 即期買入
spot_sell_rate = cols[4].text.strip() # 即期賣出
# 過濾掉沒有匯率的項目 (例如 "-" )
if (cash_buy_rate != '-' and cash_sell_rate != '-') or \
(spot_buy_rate != '-' and spot_sell_rate != '-'):
rates_data.append({
'currency': currency_name,
'cash_buy': cash_buy_rate,
'cash_sell': cash_sell_rate,
'spot_buy': spot_buy_rate,
'spot_sell': spot_sell_rate
})
return rates_data
except requests.exceptions.RequestException as e:
messagebox.showerror("網路錯誤", f"無法連接到台灣銀行網站:{e}")
return None
except Exception as e:
messagebox.showerror("擷取錯誤", f"處理網頁資料時發生錯誤:{e}")
return None
def update_exchange_display():
"""
擷取匯率數據並更新 Tkinter 介面。
"""
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
status_label.config(text=f"最後更新時間: {current_time} - 擷取中...")
root.update_idletasks() # 強制更新 GUI 以顯示訊息
rates = fetch_exchange_rates()
if rates:
# 清除舊數據
for item in tree.get_children():
tree.delete(item)
# 插入新數據
for rate in rates:
tree.insert('', tk.END, values=(
rate['currency'],
rate['cash_buy'],
rate['cash_sell'],
rate['spot_buy'],
rate['spot_sell']
))
status_label.config(text=f"最後更新時間: {current_time} - 數據已更新")
else:
# 如果沒有抓到數據,顯示錯誤訊息
for item in tree.get_children():
tree.delete(item)
tree.insert('', tk.END, values=("未能載入匯率資料,請檢查網路或網站結構", "", "", "", ""))
status_label.config(text=f"最後更新時間: {current_time} - 數據載入失敗")
# 每 5 分鐘自動更新 (300000 毫秒)
root.after(300000, update_exchange_display)
# --- Tkinter 介面設定 ---
root = tk.Tk()
root.title("台灣銀行即時牌告匯率")
root.geometry("800x750") # 調整視窗大小以容納更多欄位
# 框架用於容納 Treeview 和捲軸
frame = tk.Frame(root, padx=10, pady=10)
frame.pack(expand=True, fill="both")
# 創建 Treeview 來顯示表格數據
columns = ('currency', 'cash_buy', 'cash_sell', 'spot_buy', 'spot_sell')
tree = ttk.Treeview(frame, columns=columns, show='headings')
# 設定欄位標題
tree.heading('currency', text='幣別')
tree.heading('cash_buy', text='現金買入')
tree.heading('cash_sell', text='現金賣出')
tree.heading('spot_buy', text='即期買入')
tree.heading('spot_sell', text='即期賣出')
# 設定欄位寬度
tree.column('currency', width=150, anchor='center')
tree.column('cash_buy', width=120, anchor='center')
tree.column('cash_sell', width=120, anchor='center')
tree.column('spot_buy', width=120, anchor='center')
tree.column('spot_sell', width=120, anchor='center')
# 添加捲軸
scrollbar = ttk.Scrollbar(frame, orient="vertical", command=tree.yview)
tree.configure(yscrollcommand=scrollbar.set)
scrollbar.pack(side="right", fill="y")
tree.pack(expand=True, fill="both")
# 狀態標籤,顯示最後更新時間和狀態
status_label = tk.Label(root, text="準備載入匯率...", font=("Arial", 10), anchor="w")
status_label.pack(side="bottom", fill="x", padx=10, pady=5)
# 更新按鈕
update_button = tk.Button(root, text="手動更新匯率", command=update_exchange_display, font=("Arial", 12))
update_button.pack(pady=10)
# 初始化顯示匯率
update_exchange_display()
root.mainloop()


沒有留言:
張貼留言