• 156

(不定期更新)使用VBA解決 excel web 查詢無法匯入、匯入太慢的股市資料

wantgoo 網頁改來改去的,好麻煩,這種資料只有wantgoo 有,沒別的地方下載嗎?
…測試中…








tmwcykixe wrote:
https://www.wantgoo.com/investrue/2330/retro-monthly-candlesticks?after=1633017600000


snare wrote:
wantgoo 網頁(恕刪)



好詭異,您試可以,我卻抓不到.

snare
snare 樓主

因為程式碼要改,沒po的原因,是我還在測試認證用的參數可以用多久,能不能只抓一次,不用每次更新……測試中……

2022-01-07 16:47
請教 snare 大:
要怎麼抓 cmoney 的資料(如下列網址中最下面的 本益比的表格資料) ?
https://www.cmoney.tw/finance/f00032.aspx?s=2377

我的 VBA 很弱, 有參考 751樓的程式, 但執行 fail, 我也沒能力解決, 所以想抓 cmoney 的個股本益比表格內的資料仍困擾著我...

感謝您 !
tmwcykixe wrote:
好詭異,您試可以,我(恕刪)


放棄,key值一定要重抓,沒辦法固定,有加cloudflare保護的難搞
python有cloudflare專用套件、直接取得request headers套件,但我沒研究

用ie開網頁的偷吃步也不能用,因為wantgoo有上保護的頁面,直接取消支援ie
所以資料也拿不到


用vba WebBrowser1 ,也不行,跳保護



需要的bid、cookie、cf-ray、r、m、CF$cv$params,都成功模擬了




就卡在 s => results ,中間不知道怎麼轉換的,沒這個就拿不到X-Client-Signature
沒這個值有cookie也沒用



如果您想要手動複製,那程式碼只要加2行

用firefox、fiddler也行
(不知道為什麼chrome複製出來的常出錯?難到是我加太多奇怪的plugin)
一、f12(開發者工具)
二、https://www.wantgoo.com/stock/2330/major-investors/main-trend
三、在追踨畫面上找到main-trend-data,不是main-trend
四、手動複製2個值,Cookie、X-Client-Signature



五、程式碼中加入2行

.SetRequestHeader "Cookie", "BID=A4672B92-3858-402... 後面略
.SetRequestHeader "X-Client-Signature", "575236... 後面略





六、只要換股票代碼,key值,就需重新複製


連續查詢可能只剩,vba selenium webdriver 、python……才行
不好意思,我能力不足,沒辦法只用純vba還原,只能做到手動複製key,單次下載
可惜只差一步
g80860

板主辛苦了,謝謝你付出.

2022-01-14 8:05
GuatingChua

已經很厲害了,玩股網很難搞定

2024-10-15 11:41
htnvt241 wrote:
要怎麼抓 cmoney 的資料(如下列網址中最下面的 本益比的表格資料) ?
https://www.cmoney.tw/finance/f00032.aspx?s=2377





'請配合751樓範例修改

'…中間略…

Url = "https://www.cmoney.tw/finance/f00032.aspx?s=" & stock

'…中間略…

cmkey = Split(Split(.responsetext, "title='本益比' cmkey='")(1), "'>本益比<")(0)
Url_a = "https://www.cmoney.tw/finance/ashx/mainpage.ashx?action=GetPERAndEPSBySeason&stockId=" & stock & "&cmkey=" & cmkey

'…中間略…

Range("a1:g1") = Array("年季", "收盤價", "法人預估本益比", "本益比(近4季)", "本益比(季高)", "本益比(季低)", "EPS")

For i = 0 To CallByName(Json, "length", VbGet) - 1

Cells(i + 2, 1) = WorksheetFunction.Replace(CallByName(CallByName(Json, i, VbGet), "SeasonDate", VbGet), 5, 1, "Q")
Cells(i + 2, 2) = CallByName(CallByName(Json, i, VbGet), "ClosePr", VbGet)
'其它5筆資料請自行練習用callbyname取出

Next i




'…中間略…

htnvt241

非常感謝 snare 大大, 問題解決了! 拜服~

2022-01-10 10:10
snare wrote:
放棄,key值一定要(恕刪)


真抱歉,丟出來一個這麼難解還無解的問題,浪費您寶貴的時間。若其他網站也像wantgoo一樣,那真是難以想像。現在要抽出時間去學python,實在有點困難,也有點心有餘而力不足,再加上vba學了,沒賺到什麼錢,python肯定也不一定能賺錢,哈哈。
printf.tw wrote:
裡面有全形的空白
可...(恕刪)
如下就可結合snare大的code了
最近在麻辣看到知名的高手GBKEE,分享一個Pchome線型走勢的程式
http://forum.twbts.com/viewthread.php?tid=23550&extra=pageD1&page=2
(15樓)是用InternetExplorer方式寫的

因為我在797樓,也寫過pchome 範例,所以注意到那篇文章
本以為那個pchome網頁,和797樓一樣難搞
沒想到試了才發現,普通方式就行

試寫了一個使用xmlhttp的範例給各位參考,跟那篇InternetExplorer的範例功能是一樣的
只有差在下載時間不同,2者大約相差5倍








'股票代碼放在a欄

Sub test()

Dim i As Integer, lastrow As Integer, URL As String, sheetName As String, ttt As Double
Application.ScreenUpdating = False

ttt = Timer
sheetName = "工作表1"

With Sheets(sheetName)
.Range("B:U").Clear: .Range("b1:c1") = Array("股票名稱", "股票價格")
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
If lastrow = 1 Then Exit Sub
For i = 2 To lastrow
URL = "https://pchome.megatime.com.tw/stock/sid" & .Cells(i, 1) & ".html"
Call Get_Pchome_stock_線型走勢(sheetName, URL, i)
Next i

'=================================
'排版,請自行調整
.Cells.Font.Size = 10
.Range("a1:u1").Font.Size = 8
.Range("a1:u1").Font.Bold = True
.Columns.ColumnWidth = 10
.Columns("B:D").EntireColumn.AutoFit
'=================================

End With
Application.ScreenUpdating = True

Debug.Print Timer - ttt

End Sub

Sub Get_Pchome_stock_線型走勢(sheetName As String, URL As String, r As Integer)


Dim HTML As Object, Getxml As Object, table As Object, i As Integer, j As Integer, c As Integer
Set HTML = CreateObject("htmlfile")
Set Getxml = CreateObject("msxml2.xmlhttp")
On Error Resume Next

With Getxml

.Open "POST", URL, False
.setRequestHeader "Referer", "https://stock.pchome.com.tw/"
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.setRequestHeader "Content-Length", LenB("is_check=1")
.send ("is_check=1")

HTML.body.innerhtml = .responsetext

If InStr(.responsetext, "查無此股票") > 0 Then
Sheets(sheetName).Cells(r, 2) = "查無此股票"
Sheets(sheetName).Cells(r, 2).Font.Color = vbRed
Exit Sub
Else

'因語法問題,這行改用圖片,請手動輸入,或參考附件



End If

End With

Sheets(sheetName).Cells(r, 3) = HTML.getElementById("stock_info_data_a").innertext

'only price
'Sheets(sheetName).Cells(r, 3) = Split(HTML.getElementById("stock_info_data_a").innertext, " ")(0)

Set table = HTML.All.tags("table")(1).Rows

For i = IIf(r = 2, 2, 3) To 7 Step IIf(r > 2, 2, 1)
c = ((i - 2) \ 2) * 6 + 4
For j = 0 To table(i).Cells.Length - 1
Sheets(sheetName).Cells(IIf(r = 2, (i Mod 2) + 1, r), c) = table(i).Cells(j).innertext
c = c + 1
Next j
Next i

Set HTML = Nothing
Set Getxml = Nothing
Set table = Nothing


End Sub






[點擊下載]

樓主您好,
由於合庫銀行歷史匯率已改版為JSON,小弟試著套用範例部分程式碼,自訂區間方式,仍無法抓到資料,請樓主協助一下:

合庫網址:https://www.tcb-bank.com.tw/personal-banking/deposit-exchange/exchange-rate/historical-rate#



部分程式碼:
Dim xmlhttp As Object, Jsondata As Object, Url As String, DecodeJson, temp
Set Jsondata = CreateObject("HtmlFile")
Set xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")
Jsondata.write"<scrip>document.Jsonparse=function(S){return eval(’(’+s+’)’);}</script>"

Url = "https://www.tcb-bank.com.tw/api/client/ForeignExchange/GetHistoryForeignExchange?" & _
"__RequestVerificationToken=M_rAmBVWx_c5OlXMfeLCc3f3OFrS1BTzNqhqCkXWaMNKJ2Y_wAPOfWcQYh9zBNe2nhGH-OjdvvWPRmuM2Csh9O-Zd6GMPstY12wzwiSiW981" _
& "¤cy=USD&dateoptions=custom&startdate=2022-01-01&enddate=2022-01-22"

On Error Resume Next

Sheets("工作表1").Cells.Clear

With xmlhttp

.Open "POST", Url, False

.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.setRequestHeader "Referer", Url
.setRequestHeader "Cache-Control", "no-cache"
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.send
Debug.Print .responsetext
Set DecodeJson = Jsondata.JsonParse(.responsetext)
activer wrote:
由於合庫銀行歷史匯率已改版為JSON,小弟試著套用範例部分程式碼,自訂區間方式,仍無法抓到資料 (恕刪)


token是變動的,不能用定值
請參考 271樓、272樓、274樓、631樓、751樓、1064樓…等等,相關範例







Sub Get_tcb_bank_Json()


Dim Jsondata As Object, DecodeJson, Getxml As Object, URL As String, R_V_Token As String, URL_a As String
Dim StartDate As String, EndDate As String, CurrencyCode As String

Set Getxml = CreateObject("msxml2.xmlhttp")
Set Jsondata = CreateObject("HtmlFile")



'test
CurrencyCode = "USD"
'CurrencyCode = "JPY"
StartDate = "2022-01-01"
EndDate = "2022-01-22"

URL = "https://www.tcb-bank.com.tw/personal-banking/deposit-exchange/exchange-rate/historical-rate"
URL_a = "https://www.tcb-bank.com.tw/api/client/ForeignExchange/GetHistoryForeignExchange"

With Getxml

.Open "GET", URL, False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0"
.send


R_V_Token = Split(Split(.responsetext, """__RequestVerificationToken"" type=""hidden"" value=""")(1), """ />")(0)


.Open "POST", URL_a, False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0"
.send ("__RequestVerificationToken=" & R_V_Token & "¤cy=" & CurrencyCode & _
"&dateoptions=custom&startdate=" & StartDate & "&enddate=" & EndDate)

Set DecodeJson = CallByName(Jsondata.JsonParse(.responsetext), "result", VbGet)

End With

'json整理,請參考其它範例

Set Getxml = Nothing
Set Jsondata = Nothing



End Sub

  • 156
內文搜尋
X
評分
評分
複製連結
請輸入您要前往的頁數(1 ~ 156)
Mobile01提醒您
您目前瀏覽的是行動版網頁
是否切換到電腦版網頁呢?