簡單使用pandas整理和 matplotlib畫圖
前言
今天將會分享如何使用python爬取台灣證券交易所的大盤日交易價格以及個股交易價格,並畫出兩者價格線圖。
在開始爬蟲時都要先研究 目標是誰?結構是甚麼?我要什麼資料?希望最後的資料長怎麼樣? 在腦中有些許畫面後,我們就可以開始了!!!
將學習到
- 用
urlopen
、json
爬蟲與解析網站文字 - 使用
pandas
整理表格 - 利用
matplotlib
畫收盤價格線圖
環境設定
win11 Anaconda-jupyter Python(3.7.6)
使用套件
import json
import pandas as pd
from urllib.request import urlopen
import matplotlib.pyplot as plt
開始工作
步驟1:檢查目標
網站需要先輸入日期及股票(以110年12月及2330台積電為例)進行查詢,通常會先看上方網址(url)是否有相關的資訊,可惜並未直接看到相關資訊,則進行網頁解析。
依照網站並按滑鼠右鍵”檢查”步驟,找到”Request URL”的https://www.twse.com.tw/exchangeReport/STOCK_DAY?response=json&date=20211201&stockNo=2330&_=1643352549614
就是我們想要的資訊,date就是日期,stockNO就是股票代號,最後16…不影響爬蟲,故可以忽略。
這就是我們想要的資訊,以便後續爬蟲與資料整理。
步驟2:使爬取網站內容並整理
#需要爬蟲的網址
url = 'https://www.twse.com.tw/en/exchangeReport/STOCK_DAY?response=json&date=20211201&stockNo=2330'#解析網頁內容並轉為json
data = json.loads(urlopen(url).read())
print(data)#取得json的data欄位並用fields作為欄位名稱
df = pd.DataFrame(data[‘data’], columns=data[‘fields’])
display(df)
步驟3:將步驟2之程式碼整理成副程式(def)
#台指大盤
def read_index_price(date):
url = f’https://www.twse.com.tw/en/indicesReport/MI_5MINS_HIST?response=json&date={date}'
data = json.loads(urlopen(url).read())#將網址內容轉為json
df = pd.DataFrame(data[‘data’], columns=data[‘fields’])#取得json的data欄位並用fields作為欄位名稱
return df#個股價格
def read_stock_price(date, StockNo):
url = f’https://www.twse.com.tw/en/exchangeReport/STOCK_DAY?response=json&date={date}&stockNo={StockNo}'
data = json.loads(urlopen(url).read())#將網址內容轉為json
df = pd.DataFrame(data[‘data’], columns=data[‘fields’])#取得json的data欄位並用fields作為欄位名稱
return df#個股殖利率及本益比
def read_stock_PE(date, StockNo):
url = f’https://www.twse.com.tw/en/exchangeReport/BWIBBU?response=json&date={date}&stockNo={StockNo}'
data = json.loads(urlopen(url).read())#將網址內容轉為json
df = pd.DataFrame(data[‘data’], columns=data[‘fields’])#取得json的data欄位並用fields作為欄位名稱
return df
如果只爬取1個個股的交易資訊可能不是那麼有趣與好使用,故同時利用了步驟1、2的方法,將台灣加權指數及個股的殖利率、本益比交易資訊抓取下來,增加資訊的豐富度。
步驟4:合併步驟3抓取的資料(DataFrame)
date = ‘20211201’#需要月份
StockNo = ‘2330’#查詢股票代號#台指大盤
df_index = read_index_price(date)
display(df_index)#個股價格
df_stock_price = read_stock_price(date, StockNo)
display(df_stock_price)#個股本益比
df_stock_PE = read_stock_PE(date, StockNo)
display(df_stock_PE)#合併DataFrame
dfs = df_index.merge(df_stock_price,on=’Date’).merge(df_stock_PE,on=’Date’)
display(dfs)dfs.to_csv(f’stock_{StockNo}_{date[:6]}.csv’, index=False)#將DataFrame存成csv檔
步驟5:同時繪製台指及個股收盤價
#讀進以抓取並整理好的股票csv
dfs = pd.read_csv(f'stock_{StockNo}_{date[:6]}.csv')import matplotlib.pyplot as plt#繪圖用函示庫#將日期字串改為日期型態
dfs['Date'] = pd.to_datetime(dfs['Date'])#將股價字串改為float
dfs['Closing Index'] = dfs['Closing Index'].str.replace(',','').astype(float)
dfs['Closing Price'] = dfs['Closing Price'].astype(float)#建立圖表及設定
fig,ax = plt.subplots()
plt.xticks(rotation=45) #x軸數據顯示旋轉45度
plt.title(f'{StockNo} Closing Price') #圖表之表頭
plt.grid(axis='x') #圖表背景線條(灰線)僅顯示縱軸#繪製台灣加權指數收盤價
ax.plot(dfs['Date'], dfs['Closing Index'].astype(float),
color="blue", alpha=0.8, marker="o") #x軸資料,y軸資料,線顏色,線顏色透明度,線的標記ax.set_xlabel("Date",fontsize=12) #x軸標題,文字大小ax.set_ylabel("Closing Index",color="blue", alpha=0.8, fontsize=12) #y軸標題,顏色、顏色透明度,文字大小#繪製在上圖中,但y軸刻度(scale)不同
ax2=ax.twinx()#繪製個股(2330)收盤價
ax2.plot(dfs['Date'], dfs['Closing Price'].astype(float),
color="orange", alpha=0.8, marker="D")#x軸資料,y軸資料,線顏色,線顏色透明度,線的標記ax2.set_ylabel("Closing Price",color="orange", alpha=0.8, fontsize=12) #y軸標題,顏色、顏色透明度,文字大小fig.savefig(f'{StockNo}_{date[:6]}_price.png', bbox_inches='tight') #圖片儲存路徑及名稱,圖的儲存方式(減少空白,盡量留圖的重點)
plt.show()
步驟6:同時繪製個股收盤價及本益比
#建立圖表及設定
fig,ax = plt.subplots()
plt.xticks(rotation=45) #x軸數據顯示旋轉45度
plt.title(f'{StockNo} Dividend Yield') #圖表之表頭
plt.grid(axis='x') #圖表背景線條(灰線)僅顯示縱軸#繪製個股(2330)收盤價
ax.plot(dfs['Date'], dfs['Closing Price'].astype(float),
color="orange", alpha=0.8, marker="o") #x軸資料,y軸資料,線顏色,線顏色透明度,線的標記ax.set_xlabel("Date",fontsize=12) #x軸標題,文字大小ax.set_ylabel("Closing Index",color="orange", alpha=0.8, fontsize=12) #y軸標題,顏色、顏色透明度,文字大小#繪製在上圖中,但y軸刻度(scale)不同
ax2=ax.twinx()#繪製個股(2330)的現金殖利率
ax2.plot(dfs['Date'], dfs['Dividend yield (%)'].astype(float),
color="green", alpha=0.8, marker="D")#x軸資料,y軸資料,線顏色,線顏色透明度,線的標記ax2.set_ylabel("Dividend Yield(%)",color="green", alpha=0.8, fontsize=12) #y軸標題,顏色、顏色透明度,文字大小fig.savefig(f'{StockNo}_{date[:6]}_DividendYield.png', bbox_inches='tight') #圖片儲存路徑及名稱,圖的儲存方式(減少空白,盡量留圖的重點)
plt.show()
完整程式碼
小結
爬蟲是一種分析資料的必要工具,對於資料科學非常有用,如果你對於以上的內容有建議歡迎提出,一起討論絕對是成長的捷徑!!
參考資料
How to read a JSON response from a link in Python?
How to Make a Plot with Two Different Y-axis in Python with Matplotlib ?