[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 資 源

EXCEL & VBA功能 – 綜合筆記
※ EXCEL & VBA功能 筆記 : 將針對文章中所使用的 EXCEL 及 VBA公式 / 工具操作 / 巨集設定 / 控制項的運用,做個整合記錄,方便大家在學習當下的參考與使用。

VBA指令 – 彙整筆記
※ VBA 提供相當多的指令用法,VBA指令 彙整筆記,將會陸續記錄 VBA文章 中,所用過的 VBA指令,方便學員們對照運用。

VBA程式語法 – 彙整筆記
※ 語法就是程式的文法。 使用者要與電腦溝通,就必須遵守這些規則。VBA程式語法 筆記 : 將針對 VBA文章 中所使用的 VBA程式語法,做個整合記錄,方便大家在學習當下參考與使用。