KCouper 是一個網頁應用,用於收集、顯示和搜索 KFC (肯德基) 的電子優惠券信息。該項目旨在幫助用戶輕鬆瀏覽和比較各種 KFC 優惠券,了解每張優惠券包含的餐點項目、可更換選項以及價格信息。
KFC 台灣官網提供電子優惠券系統,用戶可以通過優惠券代碼兌換特定餐點組合。然而,官網的優惠券瀏覽體驗有限,用戶難以快速比較不同優惠券的內容和價格。KCouper 通過自動化數據收集和用戶友好的界面解決了這個問題。
- 數據收集:自動從 KFC API 獲取優惠券數據
- 數據處理:將原始 API 數據轉換為結構化的優惠券信息
- 網頁展示:提供響應式網頁界面顯示優惠券列表
- 搜索過濾:支持按餐點名稱搜索和過濾優惠券
- 詳細查看:顯示每張優惠券的完整信息和可更換選項
- 排序功能:支持按價格、代碼、到期日等多種方式排序
- 線上點餐:提供直接鏈接到 KFC 官網的點餐頁面
- 用戶收藏:支持用戶收藏喜愛的優惠券,並提供收藏過濾功能
- 響應式設計,支持桌面和移動設備
- 數據更新機制,定期刷新優惠券信息
- 用戶友好的界面,簡潔明瞭
- 性能優化,快速加載和搜索
- 後端數據收集 (
script/kfc.py):Python 腳本負責 API 調用和數據處理 - 前端界面 (
index.html,js/main.js,css/main.css):HTML/CSS/JavaScript 實現用戶界面 - 數據存儲 (
coupon.json,public/coupon.js):JSON 格式的優惠券數據 - 用戶數據存儲 (localStorage):瀏覽器本地存儲用於保存用戶收藏記錄
- Python 腳本調用 KFC API 獲取優惠券數據
- 數據處理和轉換後保存為本地文件
- 前端加載數據並動態生成界面
- 用戶通過瀏覽器與界面交互
- 環境變數:
SHOP_CODE:商店代碼 (例如:TWI104)EXCLUDE_NAMES:排除的餐點名稱列表 (逗號分隔)
- 優惠券代碼範圍:預定義的代碼範圍數組,例如
((24000, 26000), (40000, 41000), ...)
- 初始化 HTTP 會話,設置 User-Agent 和請求頭
- 調用
init_delivery_info()初始化配送信息 - 遍歷指定的優惠券代碼範圍
- 對每個代碼調用
get_coupon_data()獲取優惠券數據 - 調用
convert_coupon_data()轉換數據格式 - 收集所有有效優惠券數據
coupon.json:包含所有優惠券數據的 JSON 文件{ "coupon_by_code": { /* 按代碼索引的優惠券對象 */ }, "coupon_list": [ /* 按價格排序的優惠券數組 */ ], "count": 123, // 優惠券總數 "last_update": "2025-10-03 14:30:00" // 最後更新時間 }public/coupon.js:JavaScript 格式的數據文件,用於前端加載
- 用戶訪問
index.html網頁 - 網頁自動加載
public/coupon.js中的優惠券數據
- 頁面加載時調用
prepareInitData()生成優惠券卡片 - 調用
prepareButtons()動態生成過濾按鈕 - 用戶輸入搜索詞或點擊過濾按鈕
- 調用
filterCouponsWithNames()過濾顯示的優惠券 - 用戶選擇排序方式時調用
getSortedCoupons()重新排序
- 網頁界面顯示優惠券卡片列表
- 每個卡片包含:
- 優惠券名稱和價格
- 包含的餐點項目
- 有效期
- "查看餐點選項" 鏈接
- "線上點餐" 鏈接
- 搜索框輸入:餐點名稱關鍵字 (例如:"炸雞", "薯條")
- 過濾按鈕點擊:預定義的餐點類別按鈕
- 開關選項:"搜尋所有選項" 復選框
- 用戶輸入或選擇搜索詞
- 調用
filterCouponsWithNames(names)函數 - 檢查每個優惠券是否包含所有搜索詞
- 如果啟用"搜尋所有選項",同時搜索餐點的變體選項
- 顯示匹配的優惠券,隱藏不匹配的
- 更新顯示的優惠券數量 (
#searchResultCount) - 顯示/隱藏相應的優惠券卡片
- 搜索詞以標籤形式顯示在搜索框中
- 用戶點擊優惠券卡片上的 "查看餐點選項" 鏈接
- 觸發
couponDetailEvent()函數 - 根據優惠券代碼從
COUPONS_BY_CODE獲取詳細數據 - 生成模態框內容,包括:
- 優惠券名稱和價格
- 每個餐點項目的默認選項
- 可更換的變體選項及其加價
- 線上點餐鏈接
- 顯示模態框,包含完整的優惠券詳細信息
- 列出每個餐點的可選項和對應價格
- 用戶從下拉選單選擇排序方式:
- 價格:低→高 / 高→低
- 代碼:遞增 / 遞減
- 到期日:近→遠 / 遠→近
- 更新
currentSort變數 - 調用
getSortedCoupons()重新排序優惠券數組 - 調用
prepareInitData()重新渲染優惠券卡片
- 重新排列的優惠券卡片列表
- 保持當前的搜索過濾狀態
- 用戶訪問
index.html網頁 - 網頁自動加載收藏的優惠券數據(從 localStorage)
- 頁面加載時調用
loadFavorites()從 localStorage 加載收藏數據 - 用戶點擊優惠券卡片左上角的星號圖示:
- 如果是空心星號,加入收藏清單
- 如果是實心星號,從收藏清單移除
- 點擊後更新星號圖示狀態並保存到 localStorage
- 如果啟用"只顯示收藏"過濾,立即重新過濾顯示的優惠券
- 優惠券卡片左上角顯示星號圖示(空心/實心)
- 收藏狀態持久化存儲在瀏覽器 localStorage 中
- 收藏過濾時只顯示已收藏的優惠券
- 用戶勾選/取消勾選 "只顯示收藏" 開關
- 監聽開關狀態變化
- 調用
filterCouponsWithNames()重新過濾優惠券 - 結合當前的搜索條件,只顯示符合條件的收藏優惠券
- 動態顯示/隱藏優惠券卡片
- 更新搜索結果計數
- 在收藏過濾模式下,移除收藏會立即隱藏該優惠券
{
name: "優惠券名稱",
product_code: "產品代碼",
coupon_code: 優惠券代碼數字,
price: 價格數字,
items: [ // 餐點項目數組
{
name: "餐點名稱",
count: 數量,
addition_price: 基礎加價,
flavors: [ // 可選變體
{
name: "變體名稱",
addition_price: 加價金額
}
]
}
],
start_date: "開始日期 (YYYY-MM-DD)",
end_date: "結束日期 (YYYY-MM-DD)"
}- 502 錯誤:自動重試最多 10 次,每次等待 30 秒
- 非 200 狀態碼:記錄錯誤並拋出異常
- 無效優惠券:記錄調試信息,跳過該優惠券
- 缺少必要字段:拋出 KeyError 或 ValueError
- 數據格式異常:記錄錯誤並跳過
- 數據加載失敗:顯示默認狀態
- 用戶輸入無效:優雅降級,顯示所有優惠券
- API 調用間隔:每個請求間等待 0.3 秒,避免過載
- 範圍間等待:每個代碼範圍間等待 30 秒
- 前端渲染:使用 jQuery 動態生成 DOM 元素
- 搜索優化:使用 Set 結構存儲過濾名稱,提高查找速度
- 數據更新:運行
python script/kfc.py腳本 - 版本追蹤:通過
last_update字段記錄更新時間 - 更新日誌:網頁中顯示版本更新歷史
- requests:HTTP 請求
- python-dotenv:環境變數管理
- Bootstrap 5.3.0:UI 框架
- jQuery:DOM 操作
- jQuery UI:標籤輸入組件
- Tag-it:標籤管理插件
- 設置環境變數 (SHOP_CODE, EXCLUDE_NAMES)
- 運行數據收集腳本:
python script/kfc.py - 部署靜態文件到網頁服務器
- 用戶通過瀏覽器訪問 index.html
- 支持更多 KFC 商店
- 實現實時數據更新
- 移動應用版本
- 多語言支持
- 收藏功能增強:收藏分組、收藏備註、收藏分享