Taiwan Lotto:把官方開獎結果變成可查詢的本機資料集
用 CLI 同步、驗證並儲存大樂透與威力彩的歷史開獎資料,再透過 Web 介面查詢開獎紀錄與號碼統計。
Taiwan Lotto 目前支援大樂透與威力彩,分別可同步 2007 年與 2008 年起的官方開獎資料。所有資料都儲存在本機 SQLite 資料庫,不需連接外部資料庫服務。
問題與目標
台灣彩券會公開每期開獎結果,但若要跨年度整理或比較不同期間的資料,仍得處理歷史資料收集、API 分頁、欄位驗證、重複期別、官方更正及後續更新,才能建立一份可長期使用的資料集。
這個專案的目標,是把公開的開獎結果整理成完整、可靠的本機資料,並建立一套可重複執行的更新與查詢流程。
設計考量
- 官方 API 可能暫時無法連線、調整回傳格式,或更正近期資料,程式必須能辨識並妥善處理
- 採用單機架構,資料庫、查詢服務與操作介面都在使用者的電腦上執行
- CLI 與 Web 共用相同的彩券規則及 SQLite 資料庫,避免資料定義與查詢結果不一致
- 統計功能著重呈現不同期間的歷史分布、理論差異與未開期數
使用方式:CLI 同步,Web 查詢
一般使用只需要執行:
taiwan-lotto web
程式啟動後會依序:
- 同步最新開獎資料
- 在
http://127.0.0.1:4938啟動本機網站 - 自動開啟瀏覽器
其他使用情境:
| 指令 | 用途 |
|---|---|
taiwan-lotto sync | 只更新資料,不啟動網站 |
taiwan-lotto web --no-sync | 略過同步,直接使用現有資料庫啟動網站,適合離線查詢或除錯 |
開獎紀錄
首頁可依彩券種類及日期區間篩選資料,逐期顯示實際開出順序、特別號或第二區號碼,並以分頁方式瀏覽完整紀錄。

統計資料
統計頁可選擇全部歷史、指定日期區間或最近指定期數,分別查看主要號碼與特別號/第二區的統計結果,內容包括:
- 開出次數與開出率
- 與理論期望次數的差異
- 最近一次開出日期
- 目前連續未開期數
- 歷史最長未開期數
每個欄位都可排序,方便從開出頻率、理論差異或未開期數等角度比較資料。

三個關鍵設計
1. 重新檢查近期資料
第一次同步會按年度匯入完整歷史資料;完成後改用增量同步,從各彩券最新資料月份往前兩個月至今重新查詢。同步結果會分別列出新增、略過、更正及來源缺少的期別。
這種做法可以同時取得最新期別並納入官方後續更正。同步指令可重複執行,已存在的相同資料會自動略過。
2. 寫入前先驗證資料
來源層會檢查 API 回傳格式、分頁總筆數、重複期別、號碼範圍及各彩券的規則,並比對 API 提供的「實際開出順序」與「依號碼大小排序的結果」。只要內容不一致,就會停止該批同步;遇到暫時性的網路或伺服器錯誤,則會以指數退避方式重試。
每批資料都會在同一個 SQLite 交易中寫入;若途中發生錯誤,整批資料都不會寫入,避免只寫入部分資料。
3. Web 僅能讀取資料庫
同步流程使用可寫入的資料庫連線;Web 的查詢與統計服務則以 SQLite mode=ro 搭配 PRAGMA query_only 開啟資料庫。網站也只綁定 127.0.0.1,不接受外部連線。
系統架構
flowchart LR
Official[台灣彩券月份 API] -->|取得開獎資料| CLI[CLI<br/>解析 / 驗證 / 同步]
CLI -->|交易式寫入| DB[(SQLite)]
DB -->|唯讀查詢| Web[Web 介面<br/>FastAPI / Jinja2]
Web --> Browser[本機瀏覽器]
執行 web 時,程式會先嘗試同步資料。若同步失敗但本機已有資料庫,仍會顯示警告並使用現有資料啟動網站;只有第一次使用且尚未建立資料庫時,才會停止啟動。即使官方服務暫時無法使用,先前儲存的資料仍可繼續查詢。
成果
- 可從空白資料庫完成大樂透與威力彩的歷史資料同步,後續只需更新新增或經官方更正的期別
- 只要一個
web指令,即可完成資料更新、啟動本機網站及開啟瀏覽器 - 自動化測試涵蓋彩券規則、API 錯誤處理、同步流程、SQLite 交易及 Web 查詢
取捨與後續方向
專案採用單機架構,不需另外部署資料庫或 Web 伺服器,安裝後即可在本機同步與查詢;相對地,目前不支援遠端連線與多使用者操作。
首個版本優先完成資料驗證、同步、儲存與查詢的完整流程。未來可在現有架構上加入資料匯出與圖表功能,延伸更多資料整理及視覺化用途。
使用技術
- Python 3.13、
argparse與標準函式庫urllib - SQLite 資料庫結構版本管理、交易式寫入與唯讀查詢
- FastAPI、Jinja2 與 Uvicorn
- Pytest、Ruff、pip-audit 與 pre-commit