數據
一行程式抓取台股關鍵資料。大多數常用財報與行情都可直接取得。
下載資料
資料獲取方法,就是使用 data.get 函式,一次搞定下載 2000 檔股票 10 年以上的歷史紀錄:
| date | 1001 | ... | 2330 |
|---|---|---|---|
| 2007-04-23 | 39.65 | ... | 38.3 |
| ... | ... | ... | ... |
| 2023-05-02 | 39.85 | ... | 38.85 |
回傳型別為 FinlabDataFrame(擴充版 Pandas DataFrame)。熟悉 Pandas 可直接上手;初學者可先讀 Pandas 10 分鐘上手。
- 縱軸(row): 是市場有交易的日期的收盤價。
- 橫軸(column): 為股票代號,製作選股策略非常方便。
如何跳過要求登入?
可使用程式登入(下方有範例),免去 GUI 驗證。
還有提供哪些資料呢?
至資料庫目錄查找可用資料與鍵名。
免費資料比較短一點喔
免費用戶可下載多數資料供回測,但不含近年資料。升級 VIP 以使用最新資料。
用 AI 助手查找資料
不確定資料表名稱?在 AI 編程助手中安裝 FinLab Skill 後,直接詢問「營收相關的資料表有哪些?」即可取得正確的 data.get() 參數與用法範例。
搜尋可用欄位(data.search)
使用 data.search(keyword=None, market='tw') 搜尋可用的欄位名稱,回傳格式為 table:column。
keyword:關鍵字(不分大小寫);為None時列出全部market:'tw'(預設,台股)、'us'(美股)、'all'(台股+美股)- 無效的
market會拋出ValueError
from finlab import data
# 列出台股所有欄位(預設)
all_tw = data.search()
# 台股關鍵字搜尋
close_tw = data.search('收盤')
# 美股關鍵字搜尋
close_us = data.search('close', market='us')
# 全市場搜尋
price_all = data.search('price', market='all')
Catalog 來源:Firestore
data_categories/finlab_tw_stock(台股)、data_categories/finlab_us_stock(美股),並使用 LRU 快取。
自動登入取得歷史資料
下載前請先登入。Jupyter/Colab 會自動跳出登入視窗;VSCode/純腳本建議以程式登入:
至 會員專區 取得 API token 後登入:
更安全的寫法
可以利用環境變數設定,避免您的 API_TOKEN 外流,以下設定方式需要每次開啟 Terminal 重新設定,假如您並非軟體工程背景,可跳過此步驟。
市場與類股範圍
限定範圍可用 data.universe 設定。例如取上市櫃「水泥工業」的收盤價:
from finlab import data
with data.universe(market='TSE_OTC', category=['水泥工業']):
price = data.get('price:收盤價')
這樣就會取得在上市櫃中的水泥產業股票收盤價的資料:

市場範圍 (market)
在台灣股市,市場範圍 (market) 可選:
| 市場代碼 | 說明 |
|---|---|
ALL |
全市場,包括上市、上櫃、興櫃、公開發行等所有股票 |
TSE |
上市公司股票(在台灣證券交易所上市) |
OTC |
上櫃公司股票(在台灣證券櫃檯買賣中心上市) |
TSE_OTC |
上市櫃公司股票(包含上市及上櫃公司) |
ETF |
交易型基金,可以像股票一樣交易的基金 |
ETF 相關類股,可以使用
| 類別 | 描述 |
|---|---|
domestic_etf |
以台股為成分股之 ETF |
foreign_etf |
以國外商品為成分股之 ETF |
leveraged_etf |
槓桿型 ETF |
vanilla_futures_etf |
無槓桿期貨 ETF |
leveraged_futures_etf |
槓桿型期貨 ETF |
類股範圍 (category)
類股範圍 (category) 依行業分類,可選以下產業:
光電業
其他電子業
化學工業
半導體
塑膠工業
存託憑證
建材營造
文化創意業
橡膠工業
水泥工業
汽車工業
油電燃氣業
玻璃陶瓷
生技醫療
生技醫療業
紡織纖維
航運業
觀光事業
貿易百貨
資訊服務業
農業科技
通信網路業
造紙工業
金融
鋼鐵工業
電器電纜
電子商務
電子通路業
電子零組件
電機機械
電腦及週邊
食品工業
取消模糊比對
使用正規表達式選取:由於程式是使用 regex 來進行比對,所以會變成模糊比對,當 categories 是「其他」,則會選出所有的「其他」類股,包含「其他證券」。如果使用者如果希望選出「其他」但不想要選出「其他證券」,可以使用以下方式:
這樣就會明確指明開頭跟結尾中間,只有「其他」的類股會被選出來。
排除類股(exclude_category)
若想要在範圍內排除特定類股,可使用 exclude_category 參數。此參數支援字串或清單,並同樣採用正規表示式(regex)進行模糊比對。
from finlab import data
# 僅選取上市櫃的「水泥工業」相關類股,且排除「金融」相關類股
with data.universe(market='TSE_OTC', category=['水泥工業'], exclude_category=['金融']):
price = data.get('price:收盤價')
先後順序
exclude_category 預設為 None。若同時設有 category 與 exclude_category,系統會先選出符合 category 條件的集合,再進行 exclude_category 的排除。
常見錯誤與解決方法
錯誤 1:KeyError - 找不到資料表
現象:執行 data.get() 時拋出 KeyError
原因: - 資料表名稱拼寫錯誤(正確為「收盤價」而非「收盤」) - 該資料表不存在於資料庫中 - API Token 未設定或無效,導致無法存取資料
解決方法:
from finlab import data
# 方法 1:先搜尋正確的欄位名稱
matching_fields = data.search('收盤')
print(matching_fields)
# 輸出:['price:收盤價', 'price:成交股數', ...]
# 方法 2:使用 try-except 處理錯誤
try:
close = data.get('price:收盤價')
print(f"✅ 資料下載成功,範圍:{close.index[0]} ~ {close.index[-1]}")
except KeyError as e:
print(f"❌ 找不到資料表:{e}")
print("請使用 data.search('關鍵字') 搜尋正確的欄位名稱")
print("或至 https://ai.finlab.tw/database 查詢可用資料")
except Exception as e:
print(f"❌ 下載失敗:{e}")
print("請檢查:")
print("1. API Token 是否已設定(finlab.login('YOUR_TOKEN'))")
print("2. 網路連線是否正常")
print("3. 是否為有效的 VIP 會員")
錯誤 2:資料為空(Empty DataFrame)
現象:成功下載但 DataFrame 沒有任何資料
原因:
- 使用 data.universe() 時,篩選條件過於嚴格(如類股不存在)
- 免費用戶下載的資料不在可用範圍內
- 資料來源暫時無資料
解決方法:
from finlab import data
# 檢查下載結果是否為空
try:
with data.universe(market='TSE', category=['不存在的類股']):
close = data.get('price:收盤價')
# 檢查資料完整性
if close.empty:
print("⚠️ 警告:下載的資料為空")
print("可能原因:")
print("1. universe 篩選條件過嚴(類股名稱不存在)")
print("2. 資料表本身無資料")
raise ValueError("下載的資料為空,請檢查篩選條件")
if close.shape[0] < 10:
print(f"⚠️ 警告:資料筆數過少(僅 {close.shape[0]} 筆)")
if close.shape[1] < 10:
print(f"⚠️ 警告:股票數量過少(僅 {close.shape[1]} 檔)")
print(f"✅ 資料正常:{close.shape[0]} 個交易日,{close.shape[1]} 檔股票")
except ValueError as e:
print(f"❌ {e}")
# 檢查可用的類股清單
print("\n可用類股範圍:")
print("水泥工業、塑膠工業、半導體、電腦及週邊...")
print("完整清單請參考文件:類股範圍 (category)")
錯誤 3:網路逾時(Timeout)
現象:下載資料時長時間無回應,最終拋出 Timeout 或連線錯誤
close = data.get('price:收盤價')
# requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='...', port=443): Read timed out.
原因: - 網路連線不穩定 - 下載的資料量過大(如全市場 10 年以上資料) - 伺服器暫時無法回應
解決方法:
from finlab import data
import time
# 方法 1:縮短資料範圍
import finlab
finlab.truncate_start = '2020-01-01' # 只下載 2020 年後的資料
try:
close = data.get('price:收盤價')
except Exception as e:
if "timeout" in str(e).lower() or "timed out" in str(e).lower():
print("⚠️ 網路逾時,嘗試重試...")
time.sleep(5) # 等待 5 秒
try:
close = data.get('price:收盤價')
print("✅ 重試成功")
except Exception as retry_error:
print(f"❌ 重試失敗:{retry_error}")
print("建議:")
print("1. 檢查網路連線")
print("2. 使用 finlab.truncate_start 縮短資料範圍")
print("3. 稍後再試")
raise
else:
raise
# 方法 2:使用本地快取(如已下載過)
# finlab 會自動快取下載的資料,第二次執行時會讀取快取
錯誤 4:API Token 驗證失敗
現象:無法登入或下載資料時提示權限錯誤
原因: - API Token 錯誤或已過期 - Token 尚未啟用(新註冊但未驗證) - 帳戶權限不足(免費用戶存取 VIP 專屬資料)
解決方法:
import finlab
import os
# 方法 1:環境變數方式(推薦,避免外流)
token = os.environ.get('FINLAB_API_TOKEN')
if not token:
print("❌ 環境變數未設定 FINLAB_API_TOKEN")
print("請先執行:")
print(" MacOS/Linux: export FINLAB_API_TOKEN='YOUR_TOKEN'")
print(" Windows: set FINLAB_API_TOKEN=YOUR_TOKEN")
exit(1)
try:
finlab.login(token)
print("✅ 登入成功")
# 驗證是否可正常下載資料
from finlab import data
close = data.get('price:收盤價')
print(f"✅ 資料存取正常,最新日期:{close.index[-1]}")
except Exception as e:
print(f"❌ 登入失敗:{e}")
print("\n請檢查:")
print("1. API Token 是否正確(至 https://ai.finlab.tw/member_info 取得)")
print("2. 帳戶是否為有效的 VIP 會員")
print("3. Token 是否已啟用(新註冊需先驗證 email)")
print("4. 網路連線是否正常")
# 方法 2:檢查會員等級(判斷是否有權限下載最新資料)
close = data.get('price:收盤價')
if close.index[-1].year < 2024:
print("⚠️ 您目前使用的是免費版,僅能存取較舊的資料")
print("升級 VIP 以使用最新資料:https://ai.finlab.tw/pricing")