...

【網路爬蟲】臺灣證券交易所歷史資料教學(1)

Python進階教學


前面有提到網路爬蟲的優點與缺點,優點就是免錢,缺點就是資料格式可能會改變,需要花時間去維護,但是對於一些即時性沒有那麼強的資料,我們還是可以利用爬蟲來抓取資料,尤其是千百年格式不變的台灣各種交易所,爬取方式都相當容易,比較麻煩的就是要個別抓取不同的標的,沒辦法一次全部吐給我們,接下來我們就一步一步來撰寫臺灣證券交易所的爬蟲吧!

由於這篇文章是我第一篇教學爬蟲,步驟都會比較詳細一點,老手的就可以直接去後面複製程式碼就好了


事前準備:

開始剖析網路資料前要先準備好的東西:

  1. 開啟Anaconda Spyder IDE (【Python 3 新手村系列】 #01 Anaconda 安裝與操作簡介【Python 3 新手村系列】 #02 Anaconda IDE Spyder)
  2. 用Google Chrome開啟:臺灣證券交易所-個股日成交資訊

Step1:分析臺灣證券交易所網頁

https://www.twse.com.tw/zh/page/trading/exchange/STOCK_DAY.html

首先進入上方的證交所網頁連結,我們就可以看到以上畫面,這個就是我們的目標網站,輸入民國的年月與股票代號(ex. 2330, 2454, 0050)後,點擊查詢就可以看到那一檔股票在當月的歷史資料,在這邊我們須就對這個網頁進行一些進一步的分析,要找出他背後資料是怎麼進來的。

  1. 在網頁上空白處按滑鼠右鍵,點選「檢查」或是Ctrl+Shift+I,就可以開出上圖右邊的畫面
  2. 在最上面點選「Network」
  3. 輸入股票代號2330,並點擊查詢

仔細找一下就會在眾多連結裡面找到我們要的連結,就是上面兩個圖顯示這個連結內容,網址紅色就是可以改變的參數,第一個為日期,第二個為股票代號,第三串數字拿掉其實也不影響

https://www.twse.com.tw/exchangeReport/STOCK_DAY?response=json&date=20200921&stockNo=2330&_=1600694538744


 

Python Code

Step 1 引入套件:除了我們平常很熟悉的Pandas與Numpy外,另外需要requests來幫助我們抓取網頁內容,json幫剖析網頁的內容成json格式。

import pandas as pd
import numpy as np
import json
import requests

 

Step 2 網頁爬蟲:利用requests套件進行抓取網址內容,並轉為文字格式輸出。

url = 'https://www.twse.com.tw/exchangeReport/STOCK_DAY?response=json&date=20200921&stockNo=2330'
data = requests.get(url).text

 

data輸出結果:

Step 3 格式轉換:由上面的資料一看就知道是json格式,所以利用json去進行拆解,拆解後再傳換成pandas的DataFrame格式以方便後續的操作。

json_data = json.loads(data)
Stock_data = json_data['data']
StockPrice = pd.DataFrame(Stock_data, columns = ['Date','Volume','Volume_Cash','Open','High','Low','Close','Change','Order'])

 

Step 4 更多的格式轉換:原先爬下來的資料均為文字格式,我們這邊需要將這些文字格式轉為程式看得懂的格式,例如將民國日期轉為西元日期,將數值文字資料轉為浮點位(float),包含需要去除千分位的處理。

StockPrice['Date'] = StockPrice['Date'].str.replace('/','').astype(int) + 19110000
StockPrice['Date'] = pd.to_datetime(StockPrice['Date'].astype(str))
StockPrice['Volume'] = StockPrice['Volume'].str.replace(',','').astype(float)/1000
StockPrice['Volume_Cash'] = StockPrice['Volume_Cash'].str.replace(',','').astype(float)
StockPrice['Order'] = StockPrice['Order'].str.replace(',','').astype(float)

StockPrice['Open'] = StockPrice['Open'].str.replace(',','').astype(float)
StockPrice['High'] = StockPrice['High'].str.replace(',','').astype(float)
StockPrice['Low'] = StockPrice['Low'].str.replace(',','').astype(float)
StockPrice['Close'] = StockPrice['Close'].str.replace(',','').astype(float)

StockPrice = StockPrice.set_index('Date', drop = True)
StockPrice = StockPrice[['Open','High','Low','Close','Volume']]

 

 

完整Source Code

最後我們可以將上面的程式碼轉換為函數型態,未來只需要丟入參數就可以變更股票代號,網址中的日期參數代表要查詢哪的時間的歷史資料,證交所一次只給一個月,所以下一篇文章將會帶大家把所有股票代號與日期都丟進去,這樣才能夠將所有資料都抓下來。

(如果臺灣證券交易所網站沒改版的話,都可以正常使用,改版則必須重新剖析撰寫)

import pandas as pd
import numpy as np
import json
import requests

def Get_StockPrice(Symbol, Date):

    url = f'https://www.twse.com.tw/exchangeReport/STOCK_DAY?response=json&date={Date}&stockNo={Symbol}'

    data = requests.get(url).text
    json_data = json.loads(data)

    Stock_data = json_data['data']

    StockPrice = pd.DataFrame(Stock_data, columns = ['Date','Volume','Volume_Cash','Open','High','Low','Close','Change','Order'])

    StockPrice['Date'] = StockPrice['Date'].str.replace('/','').astype(int) + 19110000
    StockPrice['Date'] = pd.to_datetime(StockPrice['Date'].astype(str))
    StockPrice['Volume'] = StockPrice['Volume'].str.replace(',','').astype(float)/1000
    StockPrice['Volume_Cash'] = StockPrice['Volume_Cash'].str.replace(',','').astype(float)
    StockPrice['Order'] = StockPrice['Order'].str.replace(',','').astype(float)

    StockPrice['Open'] = StockPrice['Open'].str.replace(',','').astype(float)
    StockPrice['High'] = StockPrice['High'].str.replace(',','').astype(float)
    StockPrice['Low'] = StockPrice['Low'].str.replace(',','').astype(float)
    StockPrice['Close'] = StockPrice['Close'].str.replace(',','').astype(float)

    StockPrice = StockPrice.set_index('Date', drop = True)


    StockPrice = StockPrice[['Open','High','Low','Close','Volume']]
    print(StockPrice)
    return StockPrice

if __name__ == '__main__':
    data = Get_StockPrice('2317','20200921')