使用pandas的read_html爬蟲和 matplotlib畫出5秒價格線圖
前言
今天將會分享如何使用python爬取證交所的大盤指數價格並畫出線圖。
在開始爬蟲時都要先研究 目標是誰?結構是甚麼?我要什麼資料?希望最後的資料長怎麼樣? 在腦中有些許畫面後,我們就可以開始了!!!
完整程式碼將在最下方
將學習到
· pandas的read_html抓取網站表格以及簡單的整理表格
· matplotlib畫出價格線圖以及簡易的外觀
環境設定
windows Anaconda的jupyter(6.0.3)
使用套件
import pandas as pd
from datetime import datetime,timedelta
import matplotlib.pyplot as plt
開始工作
步驟1:檢查目標
下圖是證交所公布的數據,它有提供”列印/HTML”(黃色標記處),請點開。
點開後會發現就是一個完整的表格,這就是我們本篇的目標,將它爬取下來。注意網址(url)在後面有date=20211217
,當輸入不同日期,就會切換到不同日的5秒報價了,如輸入20211215就會是2021年12月15日了。
步驟2:使用pandas爬取網站並整理
pandas的read_html
非常的方便,當爬蟲發現目標網站有表格樣式的結構,可以多多利用read_html
可以直接找到我們所需要的表格。
import pandas as pd
#目標網站
date = '20211122'
url ='https://www.twse.com.tw/exchangeReport/MI_5MINS_INDEX?response=html&date={0}'.format(date)
df = pd.read_html(url)#確認有幾個表格
len(df)
#取得抓取到的表格
df = df[0]
df
上述其實就已經完成爬蟲的一大步驟了,但上面的數據並非我們想要的,我們想要的是乾淨有條理,只保留”發行量加權股價指數”和”時間”,因此將會整理爬取下來的資料。
#保留需要的欄位
df = df.iloc[:,:2]
df.columns = df.columns.get_level_values(1)#因為有兩個標頭,但只需要第1個
df.columns = ['time','price']#重新命名columns名子#將日期加入資料中
df['date'] = date
df
#想要將日期與時間結合
df[‘datetime’] = df[‘date’]+’ ‘+df[‘time’]
display(df)
透過上述的步驟可以簡易的將1日的5秒報價抓取下來,但我們在使用加權指數的時候都是需要一段時間的資料,因此接著我們就會用迴圈方式,將指定期間的報價抓取下來。要注意的是我們用了timedelta
達成日期加1天,不過難以避免有遇到休假日,故使用了try
和except
,可以避免因為沒有表格而停止run。我們還用到了pd.concat
,這是可以將陣列中多個的DataFrame疊加的指令,上述的套件指令將會附在最下面的參考資料。
import pandas as pd
from datetime import datetime,timedeltatick=[] #儲存每日的5秒K#爬蟲起始日
start_date = '2021-12-06'
start_date_p = datetime.strptime(start_date,'%Y-%m-%d')
#爬蟲終止日
end_date = '2021-12-17'
end_date_p = datetime.strptime(end_date,'%Y-%m-%d')while start_date_p <= end_date_p:
#當爬蟲有資料時
try:
#日期型態調整
start_date = datetime.strftime(start_date_p,'%Y-%m-%d')
date = start_date.replace('-','')
#爬取5秒K網站
url ='https://www.twse.com.tw/exchangeReport/MI_5MINS_INDEX?response=html&date={0}'.format(date)
df = pd.read_html(url)[0]
#資料整理
df = df.iloc[:,:2]
df.columns = df.columns.get_level_values(1)
df.columns = ['time','price']
#將日期加入columns
df['date'] = start_date
#秀出pandas表格
display(df.head(3))
print(url)
#將當日爬取的5秒K先加入陣列
tick.append(df)
#加1日到隔日
start_date_p += timedelta(1)
#當爬蟲無資料時
except:
print('pass',start_date_p)
#加1日到隔日
start_date_p += timedelta(1)#將已經爬完的tick陣列合併成DataFrame
dfs = pd.concat(tick)
dfs['datetime'] = dfs['date'] +' '+ ['dfs.time']
display(dfs)#將DataFrame輸出成csv檔
dfs.to_csv('tick.csv')
步驟3:使用matplotlib畫圖
我們將上述所儲存的csv再讀取進來,將多餘的Unnamed: 0
欄位去除,datetime
欄位的格式也調整成"時間型態",可以有利於繪製線圖的速度。
除了有5秒的資料外,可以視覺化才能夠快速的分析,以下用了幾的基本的外觀設定,有關顏色參數、外觀設計街皆放在參考資料。
df = pd.read_csv(‘tick.csv’)# 讀取上面所存的csv
df.drop(columns=['Unnamed: 0'], inplace=True)# 發現多了'Unnamed: 0'這個欄位,因此清除它
df['datetime'] = pd.to_datetime(df['datetime'])# 將時間型態轉換成"時間型態"import matplotlib.pyplot as pltfig, ax = plt.subplots()fig.set_size_inches(15, 4)# 設定圖片大小ax.set_facecolor('k')# 設定圖片背景顏色ax.plot(df['datetime'], df['price'], color='orange')# 要繪製的x軸、y軸數據以及線的顏色ax.grid(axis='x')# 設定x軸畫直線plt.xlabel('datetime')# 設定x軸的名稱plt.ylabel('price')# 設定y軸的名稱plt.title('5 second')# 設定圖的表頭名稱plt.savefig('5second.png')# 將圖片儲存plt.show()
完整程式碼
小結
寫完本篇除了是自己想要在學習路上作筆記外,同時也想分享給剛入坑的同學們,如果你對於以上的內容有建議歡迎提出,一起討論絕對是成長的捷徑!!
參考資料
pandas的dataframe合併:Merge, join, concatenate and compare
Python | datetime.timedelta() function
如何在 Pandas 中將 DataFrame 列轉換為日期時間
How to Change Background Color in Matplotlib (With Examples)