Python – 透過證交所API抓取台股歷史資料

Python – 透過證交所開放資料API抓取台股當日交易資訊

證交所提供個股日成交資訊資料集,每日更新且僅保留最新資料。資料格式類似json,可轉為pandas dataframe。抓取時需注意使用正確的「資料下載網址」,避免誤抓舊資料。程式碼示範如何下載並處理資料,包括轉換欄位類型等步驟。

個股日成交資訊

證交所在政府開放資料平台上提供了一個資料集個股日成交資訊,這裡面的資料會每日更新,並且只保留最新的資料。如果你想抓歷史股價資料,可以參考另一篇文章〈使用Python及Yahoo Finance API抓取台股歷史資料〉。

資料格式

在這個資料集中,雖然它標示的檔案格式是csv,但我用Python的request套件抓下來後,發現它的資料結構很像json。我不是很了解這兩種格式之間的轉換邏輯,總之我後來順利使用json的方式成功處理,並轉成pandas的dataframe。

不要抓錯網址

點擊「檢視資料」按鈕後,會跳出彈出式視窗,注意你要抓的網址是上面的「資料下載網址」,而不是下面「點此下載」的連結,不要看到json格式就開心複製,結果抓了好幾天的資料,卻發現價錢怎麼都一樣。即使網頁上已加註了提醒文字如下,但我也曾經當過那個笨蛋。

以下連結為本平臺協助提供多元格式參考資料 (轉檔時間:2021-06-02 11:55:44), 非即時資料, 完整資料請以機關 原始連結 為主。

直接點擊「資料下載網址」的話,瀏覽器會自動下載一個csv檔,建議跟看盤軟體比較一下當日股價是否一致。

完整程式碼

import requests
import pandas as pd
import numpy as np
import datetime
def conv_to_list(obj):
    '''
    將物件轉換為list
    '''
    if not isinstance(obj, list) :
        results = [obj]
    else:
        results = obj
    return results

def df_conv_col_type(df, cols, to, ignore=False):
    '''
    一次轉換多個欄位的dtype
    '''
    cols = conv_to_list(cols)
    for i in range(len(cols)):
        if ignore :
            try:
                df[cols[i]] = df[cols[i]].astype(to)
            except:
                print('df_conv_col_type - ' + cols[i] + '轉換錯誤')
                continue
        else:
            df[cols[i]] = df[cols[i]].astype(to)
    return df

def date_get_today(with_time=False):
    '''
    取得今日日期,並指定為台北時區
    '''
    import pytz
    central = pytz.timezone('Asia/Taipei')
    
    if with_time == True:
        now = datetime.datetime.now(central)
    else:
        now = datetime.datetime.now(central).date()
    return now

# 下載證交所資料 ------
link = 'https://www.twse.com.tw/exchangeReport/STOCK_DAY_ALL?response=open_data'
data = pd.read_csv(link)
# ['證券代號', '證券名稱', '成交股數', '成交金額', '開盤價',
#  '最高價', '最低價', '收盤價', '漲跌價差', '成交筆數']
data.columns = ['STOCK_SYMBOL', 'NAME', 'TRADE_VOLUME', 'TRADE_VALUE', 
                'OPEN', 'HIGH' ,'LOW', 'CLOSE', 'PRICE_CHANGE', 'TRANSACTION']   
# 標註今日日期
data['WORK_DATE'] = date_get_today()
cols = data.columns.tolist()
cols = cols[-1:] + cols[:-1]
data = data[cols]
# 除了證券代號外,其他欄位都是str,且部份資料中有''
data = data.replace('', np.nan, regex=True)
# 將data type轉為float
data = df_conv_col_type(df=data, 
                        cols=['VOLUME', 'TRADE_VALUE', 'OPEN', 'HIGH' ,'LOW',
                              'CLOSE', 'PRICE_CHANGE', 'TRANSACTION'],
                        to='float')

台股歷史股價與趨勢預測

〈台股歷史股價與趨勢預測〉就是從Yahoo Finance抓取歷史資料,並透過證交所API每日更新。實際佈署方式是使用PythonAnyWhere和Plotly,可以參考〈在網頁上發佈動態資料圖表 – 方案評估與技術問題全記錄〉。

20230116更新

比起證交所的開放資料或Yahoo Finance API,我發現另外一個更優質的資料來源 ─ 富果Fugle,請參考〈使用Python與富果API下載台股歷史資料〉。

如果你只是想交易,對數據分析與機器學習的興趣不大

那你可以參考我的模型預測結果。此資料僅供學術研究之用途,如您以此進行任何金融操作,請自行承擔風險與後果。

https://aronhack.com/zh/taiwan-stock-market-prediction-zh/

🚀 以每年 5 美元解鎖無廣告體驗

✓ 14 天免費試用 ✓ 隨時取消

在〈Python – 透過證交所開放資料API抓取台股當日交易資訊〉中有 13 則留言

  1. I am now not sure the place you’re getting your information, but good topic. I must spend some time studying more or working out more. Thank you for great information I was searching for this information for my mission.

  2. 要成立指數期貨操盤室、需要專用电腦看盤軟體、請問有那些廠商可報價.

  3. 您好有一問題請教, 依您上述建議下載資料程式碼, 仍有錯誤訊息, 如下: PS C:\Python\Python396> & C:/Python/Python396/python.exe c:/Python/Python396/daystock.py Traceback (most recent call last): File “c:\Python\Python396\daystock.py”, line 64, in data = data.replace(”, np.nan, regex=True) NameError: name ‘np’ is not defined 不知要如何修改呢?

    1. 是我少寫了一行,沒有匯入numpy,只要加上下面這一行應該就可以囉。 import numpy as np

    2. 初學者請多包涵. 我加了一行import numpy as np, 就出現以下資訊: Traceback (most recent call last): File “C:\Python\Python396\lib\site-packages\pandas\core\indexes\base.py”, line 3361, in get_loc return self._engine.get_loc(casted_key) File “pandas\_libs\index.pyx”, line 76, in pandas._libs.index.IndexEngine.get_loc File “pandas\_libs\index.pyx”, line 108, in pandas._libs.index.IndexEngine.get_loc File “pandas\_libs\hashtable_class_helper.pxi”, line 5198, in pandas._libs.hashtable.PyObjectHashTable.get_item File “pandas\_libs\hashtable_class_helper.pxi”, line 5206, in pandas._libs.hashtable.PyObjectHashTable.get_item KeyError: ‘VOLUME’ The above exception was the direct cause of the following exception: Traceback (most recent call last): File “c:\Python\Python396\daystock.py”, line 68, in data = df_conv_col_type(df=data, File “c:\Python\Python396\daystock.py”, line 31, in df_conv_col_type df[cols[i]] = df[cols[i]].astype(to) File “C:\Python\Python396\lib\site-packages\pandas\core\frame.py”, line 3455, in __getitem__ indexer = self.columns.get_loc(key) File “C:\Python\Python396\lib\site-packages\pandas\core\indexes\base.py”, line 3363, in get_loc raise KeyError(key) from err KeyError: ‘VOLUME’

    1. 我沒有找到其他類似的資料源,但如果你是用Python的話,可以試試看用OpenCV的方式辨識驗證碼的文字,但就有會有一些技術工作要做,搜尋python recognize captcha之類的關鍵字應該就會有了。以下是我找到的兩篇內容,讓你參考。 Decoding captchas using Python Bypass Captcha using 10 lines of code with Python, OpenCV & Tesseract OCR engine

  4. 您好,想請問您在政府開放資料平台上抓取的個股日成交資訊是否也會有亂碼跟錯位的問題?

    1. 我抓下來是正常的,或是你可以在requests後面加上下面這一行試試看。 r.encoding = ‘utf-8’

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *