[VBA] 自動上網爬取「 本益比 」– 找出被低估的股票
目錄 :
何謂「 本益比 」?
※「 本益比 」: 簡稱 : PE。是股票投資中經常使用的一種重要指標,主要用來評估一家公司的股價是否合理,是否值得投資的參考依據。
( PS. 本益比也可表示成 : 買進股票後,幾年可還本。若本益比數值越小,代表股價越便宜,相對的投資,就能越快回本。)
「 本益比 」 計算公式
[ 本益比/ 計算公式 ] :
[ 舉例 ] :
◎ 有二家公司股價皆為 : 100元,但 A公司 EPS : 5元,B公司 : 10元,相較之下,哪家公司較值得投資 ?
→ A公司股價 : 100元 / EPS : 5元 = 20倍本益比 ( * 表示 : 20年,才能還本。)
→ B公司股價 : 100元 / EPS : 10元 = 10倍本益比 ( * 表示 : 10年,就能還本。) → 勝出 !
如何上網查詢「 本益比 」資料 ?
※ 要想完全抓取全部股票的本益比資料,必須分二部分抓取 :
[ 1 ] : 證交所 : 意指抓取上市公司股票本益比。
[ 2 ] : 櫃買中心 : 意指抓取上櫃公司股票本益比。
◎ 證交所 : 查詢網址 — 如下 : https://www.twse.com.tw/zh/trading/historical/bwibbu-day.html。
◎ 櫃買中心 : 查詢網址 — 如下 : https://www.tpex.org.tw/web/stock/aftertrading/peratio_analysis/pera.php?l=zh-tw。
( PS. 證交所與櫃賣中心為了方便投資者查詢個股盤後相關資料,不僅提供當日個股 本益比/ 殖利率/ 股價淨值比 的查詢資料,同時也能查詢近18年的歷史資料。)
[ 本益比排行 查詢網站 ] :
◎ 玩股網 : https://www.wantgoo.com/stock/ranking/per ( 由小到大 排列 )
本益比 的意義與分析
◎ 本益比高/低 — 提供有關投資選擇的重要信息。一般來說 :
[ A ] : 低本益比 : 暗示著市場對公司的盈利前景,抱持著懷疑態度;這也或許是一個潛在的投資機會,因為它暗示公司的股價可能被低估。
[ B ] : 高本益比 : 表明市場對公司的前景非常樂觀;但這也可能是一種風險,因為股價可能被高估。
◎ 投資者在分析個股本益比時,應該與 同行業的平均值 進行比較。
[ A ] : 低於同行 : 一家公司的本益比低於同行業平均值的本益比,表示公司有被低估的可能性,但也可能是公司盈利衰退的原因。
[ B ] : 高於同行 : 一家公司的本益比高於同行業平均值的本益比,可能意味著該公司的股價相對較高,需要更多的盈利來支撐這種評價。
本益比 的注意事項
※ 投資者應該意識到,本益比並不是唯一衡量公司價值的指標。它必須增加一些參考因子,如 : 公司的成長潛力 / 競爭優勢 / 管理層的能力等。
[ A ] : 一家高成長的公司 — 可能擁有較高的本益比,但這並不一定意味著它的股票過於昂貴。
[ B ] : 一家穩定但成長緩慢的公司 — 可能擁有較低的本益比,但這不代表它是一個理想的投資標的。
[ 注意事項 ] :
※ 本益比會受在市場擔憂或興奮的情況下,暫時失去反映公司價值的功能。
VBA 實作 — 爬取當日/本益比資訊
※ 台股 分成 : 上市 / 上櫃 / 興櫃 三種股票類型。一般常用來做投資觀察的是 上市 跟 上櫃 二種。( PS. 故只針對此二種股票類型,做本益比資料分析。)
爬取上市公司當日/本益比資訊
※ 證交所(上市公司) / 當日本益比查詢網址 : https://www.twse.com.tw/zh/trading/historical/bwibbu-day.html。
◎ 網頁畫面 — 參考下圖。
[ 操作步驟 ] :
[ 1 ] : 輸入證交所本益比網址 : https://www.twse.com.tw/zh/trading/historical/bwibbu-day.html。進入上述畫面。
[ 2 ] : 輸入查詢日期 : 原預設日期就是當日收盤後的本益比資料,無須更動日期資料。( PS. 若想查詢歷史本益比,有長達18年的本益比資料,可供查詢。)
[ 3 ] : 選擇顯示筆數 : 原預設筆數為 : 10筆,若想改為顯示全部的股票資料,則將其下拉式選項改為 : 全部,即可。
[ 4 ] : 點選 列印 / HTML : 游標移至 列印 / HTML 位置,按 : 滑鼠左鍵,系統會自動開分頁,顯示當日查詢的本益比網頁資料。網址為 : https://www.twse.com.tw/rwd/zh/afterTrading/BWIBBU_d?date=20230810&selectType=ALL&response=html,此網址便是之後VBA錄製巨集時,所需的網址資料。
[ 參考畫面 ] :
錄製巨集 — 下載證交所當日本益比資料
[ 操作步驟 / 錄製巨集 ] :
[ A ] : 錄製巨集 : 請參考 錄製巨集(舊版) 內的錄製步驟,錄製完,會在新增的工作表( 當日TSE本益比 ),產生當日收盤後全部個股的本益比資料。( PS. 開頭定位在 A1。)
◎ 在製作過程中,須注意的三點 :
1. 新增活頁簿,設定檔名 : 每日爬取本益比資料.xlsm。
2. 新增工作表,設定名稱 : 當日TSE本益比。
3. 從WEB(舊版) 抓取資料時,URL 網址輸入框內,需輸入剛擷取出來的本益比資料網址 :
https://www.twse.com.tw/rwd/zh/afterTrading/BWIBBU_d?date=20230810&selectType=ALL&response=html。
[ B ] : 證交所擷取出來的 本益比 / 盤後 表格資料,存放於 當日TSE本益比 工作表內,顯示如下 :
[ 程式碼 / 爬取上市公司當日本益比 ] :
Sub 爬取上市公司本益比資料()
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;https://www.twse.com.tw/rwd/zh/afterTrading/BWIBBU_d?date=20230810&selectType=ALL&response=html" _
, Destination:=Range("$A$1"))
' .CommandType = 0
' .Name = "BWIBBU_d?date=20230810&selectType=ALL&response=html"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlAllTables
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
.Delete
End With
End Sub
[ 注意 ] : 使用舊版爬取出來的資料,會在執行 .CommandType = 0 時,出現錯誤訊號。此時,只要將其註解( ‘ ) 掉,就沒事了。
( PS. 另外,在程式後段加上 .Delete (切斷連線),這樣系統就不會造成連線膨脹,導致當機。)
爬取上櫃公司當日/本益比資訊
※ 櫃買中心(上櫃公司) / 當日本益比查詢網址 : https://www.tpex.org.tw/web/stock/aftertrading/peratio_analysis/pera.php?l=zh-tw。
◎ 網頁畫面 — 參考下圖。
[ 操作步驟 ] :
[ 1 ] : 輸入櫃買中心本益比網址 : https://www.tpex.org.tw/web/stock/aftertrading/peratio_analysis/pera.php?l=zh-tw。
[ 2 ] : 輸入查詢日期 : 原預設日期就是當日收盤後的本益比資料,無須更動日期資料。( PS. 若想查詢歷史本益比,可追朔至民國96年之本益比資料。)
[ 3 ] : 點選 列印 / HTML : 游標移至 列印 / HTML 位置,按 : 滑鼠左鍵,系統會自動開啟分頁,顯示當日查詢的本益比網頁資料。網址為 : https://www.tpex.org.tw/web/stock/aftertrading/peratio_analysis/pera_result.php?l=zh-tw&o=htm&d=112/08/11&c=&s=0,asc,此網址便是之後VBA錄製巨集時,所需的網址資料。
[ 參考畫面 / 上櫃公司股票本益比 ] :
改寫程式碼 — 爬取上櫃公司本益比資料
※ 取得上櫃公司的資料網址後,便可直接改寫上市公司的本益比程式碼,用於爬取上櫃公司之本益比資料。
( PS. 因二程式碼皆相同,唯獨爬取的目標網址不同而已,故將其網址修改,便能取得上櫃公司的本益比資料。)
[ 操作步驟 / 改寫程式碼 ] :
1. 再新增一工作表,設定名稱 : 當日OTC本益比。
2. 複製一組 爬取上市公司本益比資料 程式碼,將其名稱與爬取網址改寫成 : https://www.tpex.org.tw/web/stock/aftertrading/peratio_analysis/pera_result.php?l=zh-tw&o=htm&d=112/08/11&c=&s=0,asc。
◎ 上櫃公司擷取出來的 本益比 / 盤後 表格資料,存放於 當日OTC本益比 工作表內,顯示如下 :
[ 程式碼 / 爬取上櫃公司當日本益比 ] :
Sub 爬取上櫃公司本益比資料()
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;https://www.tpex.org.tw/web/stock/aftertrading/peratio_analysis/pera_result.php?l=zh-tw&o=htm&d=112/08/11&c=&s=0,asc" _
, Destination:=Range("$A$1"))
' .CommandType = 0
' .Name = "BWIBBU_d?date=20230810&selectType=ALL&response=html"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlAllTables
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
.Delete
End With
End Sub
整合本益比資料
※ 取得上市/上櫃公司股票本益比資料後,便可將其整合/排序。
[ 整合步驟 ] :
1. 新增工作表,設定名稱 : 當日本益比整合。
2. 複製 上市公司之本益比資料 至 當日本益比整合 工作表 A1 開頭位址。
3. 複製 上櫃公司之本益比資料 至 當日本益比整合 工作表 A行 資料最下方之空白位址。
◎ 上市/上櫃公司之資料整合圖表 :
[ 程式碼 / 複製上市公司本益比資料 ] :
Sheets("當日TSE本益比").Select ' 切換至"當日TSE本益比"工作表。
lastTSErow = [A1].End(xlDown).Row ' 找出A行資料之最後一列(Row)的列號。
Range("A2:E" & lastTSErow).Copy ' 拷貝資料 : 從 A2 ~ E行最後一列 的所有資料。
Sheets("當日本益比整合").[A1].PasteSpecial Paste:=xlPasteAll ' 將拷貝資料 -- 貼於"當日本益比整合"工作表A1欄位開始的位置。
Sheets("當日本益比整合").Columns("C:D").Delete ' 再將"當日本益比整合"工作表中C與D行的資料刪除。
[ 程式碼 / 複製上櫃公司本益比資料 ] :
Sheets("當日OTC本益比").Select ' 切換至"當日OTC本益比"工作表。
lastOTCrow = [A1].End(xlDown).Row ' 找出A行資料之最後一列(Row)的列號。
Range("A3:C" & lastOTCrow).Copy ' 拷貝資料 : 從 A3 ~ C行最後一列 的所有資料。
newRow = Sheets("當日本益比整合").[A1].End(xlDown).Row + 1 ' 找出"當日本益比整合"工作表A行最後一列之列號 + 1 = 最新一空白列。
Sheets("當日本益比整合").Range("A" & newRow).PasteSpecial Paste:=xlPasteAll ' 將拷貝資料 -- 貼於"當日本益比整合"工作表A行往下找最新空白列開始的位置。
展示/ 本益比大小排列
◎ 將上市/上櫃公司股票本益比 — 從小到大排列 的展示畫面。
[ 程式碼 / 本益比從小到大排序 ]
Sub 本益比_從小到大排序()
lastRow = [A1].End(xlDown).Row
Range("A2:C" & lastRow).Sort Key1:=Range("C2"), Order1:=xlAscending, Header:=xlNo
End Sub
[ 語法解析 ] :
◎ lastRow = [A1].End(xlDown).Row : 找出最底層資料的列號(Row)位置。( PS. 語法參考 : End 函數用法。)
◎ Range(“A2:C” & lastRow).Sort Key1:=Range(“C2”), Order1:=xlAscending, Header:=xlNo : 將A3起頭的所有資料源,依照本益比欄位(E3起頭),作從小到大的排序,不含表頭(Header)。( PS. 語法參考 : Sort 函數用法。)
修改成當日自動爬取版本
※ 本益比排序程式寫到這,將近尾聲,但要注意二個地方,那就是爬取上市與上櫃公司本益比資料時,語法「 日期 」是固定寫死的,若不將其改成「 變數 」設定,便無法達成自動化的目的。
※ 語法修改如下 :
[ 上市公司 / 原網址語法 ] :
◎ https://www.twse.com.tw/rwd/zh/afterTrading/BWIBBU_d?date=20230811&selectType=ALL&response=html
[ 程式碼 / 上市公司當日自動爬取語法 ] :
xToday = Format(Now(), "yyyymmdd")
https://www.twse.com.tw/rwd/zh/afterTrading/BWIBBU_d?date=" & xToday & "&selectType=ALL&response=html
[ 上櫃公司 / 原網址語法 ] :
◎ https://www.tpex.org.tw/web/stock/aftertrading/peratio_analysis/pera_result.php?l=zh-tw&o=htm&d=112/08/11&c=&s=0,asc
[ 程式碼 / 上櫃公司當日自動爬取語法 ] :
chineseDate = Int(Left(xToday, 4) - 1911) & "/" & Mid(xToday, 5, 2) & "/" & Right(xToday, 2) ' 文字組合成 -- 112/08/11。
https://www.tpex.org.tw/web/stock/aftertrading/peratio_analysis/pera_result.php?l=zh-tw&o=htm&d=" & chineseDate & "&c=&s=0,asc
※ 語法修改完成,自動爬取本益比程式就大功告成了。
[ 注意 ] :
※ 只要是原工作表的資料更新,請務必將舊有的資料清除(ClearContents),才不會導致資料覆蓋不足,而造成資料錯誤。
完整程式碼
[ 程式碼 / 爬取當日本益比資料 ] :
Sub 爬取當日本益比資料()
Sheets("當日本益比整合").Columns("A:C").ClearContents ' 將舊資料刪除,才不會造成資料錯誤 !
xToday = Format(Now(), "yyyymmdd")
Sheets("當日TSE本益比").Select
Columns("A:G").ClearContents
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;https://www.twse.com.tw/rwd/zh/afterTrading/BWIBBU_d?date=" & xToday & "&selectType=ALL&response=html" _
, Destination:=Range("$A$1"))
' .CommandType = 0
' .Name = "BWIBBU_d?date=20230810&selectType=ALL&response=html"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlAllTables
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
.Delete
End With
lastTSErow = [A1].End(xlDown).Row
Range("A2:E" & lastTSErow).Copy
Sheets("當日本益比整合").[A1].PasteSpecial Paste:=xlPasteAll
Sheets("當日本益比整合").Columns("C:D").Delete
' -------------------------------------------------------------------------------------------------------------------
chineseDate = Int(Left(xToday, 4) - 1911) & "/" & Mid(xToday, 5, 2) & "/" & Right(xToday, 2)
Sheets("當日OTC本益比").Select
Columns("A:G").ClearContents
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;https://www.tpex.org.tw/web/stock/aftertrading/peratio_analysis/pera_result.php?l=zh-tw&o=htm&d=" & chineseDate & "&c=&s=0,asc" _
, Destination:=Range("$A$1"))
' .CommandType = 0
' .Name = "BWIBBU_d?date=20230810&selectType=ALL&response=html"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlAllTables
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
.Delete
End With
lastOTCrow = [A1].End(xlDown).Row
Range("A3:C" & lastOTCrow).Copy
newRow = Sheets("當日本益比整合").[A1].End(xlDown).Row + 1
Sheets("當日本益比整合").Range("A" & newRow).PasteSpecial Paste:=xlPasteAll
' -------------------------------------------------------------------------------------------------------------------
Sheets("當日本益比整合").Select
lastRow = [A1].End(xlDown).Row
Range("A2:C" & lastRow).Sort Key1:=Range("C2"), Order1:=xlAscending, Header:=xlNo ' 不含表頭 -- 從小到大排列 !
End Sub
結論
本益比是股票投資中經常使用的一種重要指標,可以幫助投資者初步評估公司的投資價值。本文透過VBA的腳本設計,每日自動爬取上市櫃股票最新的本益比數據,並利用排序的方式,將其本益比資料由小到大排序,有利於查找目前最有可能被低估的股票資料。
相 關 文 章
[ 1 ] : 自動上網爬取「 本益比 」 — 找出被低估的股票
※「 本益比 」是股票投資中經常使用的一種重要指標,可以幫助投資者初步評估公司的投資價值。本文透過VBA的腳本設計,每日自動爬取上市櫃股票最新的本益比數據,並利用排序的方式,將其本益比資料由小到大排序,有利於查找目前最有可能被低估的股票資料。
[ 2 ] : 自動爬取上市櫃股票近16年「 歷史本益比 」
※ 「 歷史本益比 」是一個寶貴的數據庫,通過分析一家公司過去一段時間的本益比趨勢,投資人可以從中獲得許多有價值的洞察,更加方便地了解一家公司的投資價值和市場評價。文中,藉由VBA程式的設計,一鍵執行 / 自動將上市櫃所有股票近16年的本益比資料,全部抓進EXCEL,有利於投資人洞察所有個股的本益比趨勢。
[ 3 ] :「 本益比多少合理 ? 」史上最佛心的VBA教學 — 算出 合理本益比
※「 合理本益比 」是指一家公司的股票在特定時刻或特定市場環境下,被認為是合理價值的價益比率。文中,藉由VBA程序計算歷史本益比均值 / 運用QueryTable工具爬取個股EPS / 借助DDE語法抓取個股即時數據,求得個股合理價位,最後再以黃金切割率來定義便宜價與昂貴價,完成上市櫃所有股票的數據設定。
V B A 資 源