Python爬蟲:台灣加權指數、個股日報價及殖利率

MinKuan
11 min readJan 28, 2022

--

簡單使用pandas整理和 matplotlib畫圖

前言

今天將會分享如何使用python爬取台灣證券交易所的大盤日交易價格以及個股交易價格,並畫出兩者價格線圖。

在開始爬蟲時都要先研究 目標是誰?結構是甚麼?我要什麼資料?希望最後的資料長怎麼樣? 在腦中有些許畫面後,我們就可以開始了!!!

將學習到

  • urlopenjson爬蟲與解析網站文字
  • 使用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:檢查目標

https://www.twse.com.tw/en/indicesReport/MI_5MINS_HIST

網站需要先輸入日期及股票(以110年12月及2330台積電為例)進行查詢,通常會先看上方網址(url)是否有相關的資訊,可惜並未直接看到相關資訊,則進行網頁解析。

滑鼠右鍵”檢查” -> 選取"Network" -> 再點擊網頁中"查詢" -> “Name”中”Headers”的”General”之”Request URL”

依照網站並按滑鼠右鍵”檢查”步驟,找到”Request URL”的https://www.twse.com.tw/exchangeReport/STOCK_DAY?response=json&date=20211201&stockNo=2330&_=1643352549614就是我們想要的資訊,date就是日期,stockNO就是股票代號,最後16…不影響爬蟲,故可以忽略。

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

這就是我們想要的資訊,以便後續爬蟲與資料整理。

步驟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)
抓取下來後使用DataFrame(2330台積電之日交易資訊)

步驟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()

完整程式碼

小結

爬蟲是一種分析資料的必要工具,對於資料科學非常有用,如果你對於以上的內容有建議歡迎提出,一起討論絕對是成長的捷徑!!

參考資料

python爬蟲 — 個股歷年股價資訊

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 ?

如何在 Matplotlib 中旋轉 X 軸刻度標籤文字

--

--

MinKuan
MinKuan

No responses yet