如何取得即時的股價資訊?
進入證交所提供的基本市況報導網站,在右上方輸入股票代號(以 2330 台積電為例)。你可以看到當日的最高、最低、成交價量以及最佳五檔等資訊。
此時在網頁上點選右鍵開啟 Inspect (檢查),打開 DevTools 並切換到 Network 欄位進行觀察:
你會發現網頁會持續發送 Request 到某個網址,名稱開頭是 getStockInfo,這就是我們要的數據源。
import requests
url = "https://mis.twse.com.tw/stock/api/getStockInfo.jsp?ex_ch=tse_2330.tw"
res = requests.get(url)
res.json()
得到一個排列整齊的json
{'queryTime': {'stockInfoItem': 4329,
'sessionKey': 'tse_2330.tw_20200908|',
'sessionStr': 'UserSession',
'sysDate': '20200908',
'sessionFromTime': -1,
'stockInfo': 2084673,
'showChart': False,
'sessionLatestTime': -1,
'sysTime': '12:05:35'},
'referer': '',
'rtmessage': 'OK',
'exKey': 'if_tse_2330.tw_zh-tw.null',
'msgArray': [{'n': '台積電',
'g': '281_174_260_166_385_',
'u': '468.5000',
'mt': '060262',
'o': '428.0000',
'ps': '593',
'tk0': '2330.tw_tse_20200908_B_9998775018',
'a': '430.5000_431.0000_431.5000_432.0000_432.5000_',
'tlong': '1599537930000',
't': '12:05:30',
'it': '12',
'ch': '2330.tw',
'b': '430.0000_429.5000_429.0000_428.5000_428.0000_',
'f': '143_239_162_400_391_',
'w': '383.5000',
'pz': '428.0000',
'l': '427.5000',
'c': '2330',
'v': '16843',
'd': '20200908',
'tv': '-',
'tk1': '2330.tw_tse_20200908_B_9998774678',
'ts': '0',
'nf': '台灣積體電路製造股份有限公司',
'y': '426.0000',
'p': '0',
'i': '24',
'ip': '0',
'z': '-',
's': '-',
'h': '433.0000',
'ex': 'tse'}],
'userDelay': 5000,
'rtcode': '0000',
'cachedAlive': 7891}
在爬取網址時,不要亂刪後面的query parameters,除非你確認過差別是甚麼。
如果不能爬,Request Headers就是你要注意的地方。
理解和實驗精神
比較一下哪個是我們要的資訊:
u: 漲停v: 跌停z: 當盤成交價 (有時會顯示-)s: 當盤成交量a: 賣出最佳五檔價f: 賣出最佳五檔量l: 當日最低h: 當日最高
其他參數可以再自行觀察。如果今天你想專注於某支股票的狀態,例如盤中是否有大單進出,可以重複請求該 URL 並解析 JSON 做判斷。
若想要獲取多支股票的即時資訊,可以參考下方的處理方式。
url = "https://mis.twse.com.tw/stock/api/getStockInfo.jsp?ex_ch=tse_2330.tw|tse_3008.tw"
res = requests.get(url)
res.json()
輸出結果
{'msgArray': [{'tv': '-',
'ps': '593',
'pz': '428.0000',
'tk0': '2330.tw_tse_20200908_B_9998612907',
'tk1': '2330.tw_tse_20200908_B_9998612502',
'a': '430.5000_431.0000_431.5000_432.0000_432.5000_',
'b': '430.0000_429.5000_429.0000_428.5000_428.0000_',
'c': '2330',
'd': '20200908',
'ch': '2330.tw',
'tlong': '1599539970000',
'f': '177_171_163_437_415_',
'ip': '0',
'g': '213_170_270_177_399_',
'mt': '781884',
'h': '433.0000',
'i': '24',
'it': '12',
'l': '427.5000',
'n': '台積電',
'o': '428.0000',
'p': '0',
'ex': 'tse',
's': '-',
't': '12:39:30',
'u': '468.5000',
'v': '18197',
'w': '383.5000',
'nf': '台灣積體電路製造股份有限公司',
'y': '426.0000',
'z': '-',
'ts': '0'},
{'tv': '-',
'ps': '13',
'pz': '3560.0000',
'tk0': '3008.tw_tse_20200908_B_9998620312',
'tk1': '3008.tw_tse_20200908_B_9998619496',
'a': '3540.0000_3545.0000_3550.0000_3555.0000_3560.0000_',
'b': '3535.0000_3530.0000_3525.0000_3520.0000_3515.0000_',
'c': '3008',
'd': '20200908',
'ch': '3008.tw',
'tlong': '1599539952000',
'f': '2_2_4_12_6_',
'ip': '0',
'g': '7_9_9_19_14_',
'mt': '706396',
'h': '3580.0000',
'i': '26',
'it': '12',
'l': '3515.0000',
'n': '大立光',
'o': '3560.0000',
'p': '0',
'ex': 'tse',
's': '-',
't': '12:39:12',
'u': '3915.0000',
'v': '444',
'w': '3205.0000',
'nf': '大立光電股份有限公司',
'y': '3560.0000',
'z': '-',
'ts': '0'}],
'referer': '',
'userDelay': 5000,
'rtcode': '0000',
'queryTime': {'sysDate': '20200908',
'stockInfoItem': 852,
'stockInfo': 304464,
'sessionKey': 'tse_2330.tw_20200908|tse_3008.tw_20200908|',
'sessionStr': 'UserSession',
'sysTime': '12:39:35',
'showChart': False,
'sessionFromTime': -1,
'sessionLatestTime': -1},
'rtmessage': 'OK'}
使用 | 符號隔開代號即可完成多支股票的抓取。
整體而言,證交所的 API 非常友善,資料結構穩定且易於解析。爬蟲的核心在於利用瀏覽器的開發者工具(DevTools)找到真正的數據來源。
在開發時請注意請求頻率,避免因高頻存取導致 IP 被暫時封鎖。