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

請問一下~
上一個寫法比較吃電腦資源且速度比較慢~

後來我換了程式寫法~這一個是有抓到~

但一樣會顯示空白~
現在要進入頁面後按查詢才能~

要怎麼改程式碼才行呢?

沒有按查詢所以無法顯示出來
--------------------------------------------------------------------------------------------------------
Dim Xml_http As Object, Clipboard As Object, Urla As String
Set Clipboard = CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
Set Xml_http = CreateObject("Microsoft.Xmlhttp")

Urla = "" & Sheets("查詢").Range("W5").Value & ""

'On Error Resume Next
With Xml_http
.Open "GET", Urla, False'這邊使用GET沒用POST
.setRequestHeader "Cache-Control", "no-cache"
.setRequestHeader "Pragma", "no-cache"
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
.send
'If Err.Number <> 0 Then Err.Clear: MsgBox "上櫃資料" & vbNewLine & "下載失敗"
End With


Clipboard.SetText Xml_http.responseText
Clipboard.PutInClipboard

With Sheets("查詢")
.Select
.Range("A6").Select
.PasteSpecial NoHTMLFormatting:=True
.Columns.AutoFit
End With

Set Xmlhttp = Nothing
Set Clipboard = Nothing
------------------------------------------------------------------------------------------------------
Sheets("查詢").Range("W5")中的網址是下面
https://goodinfo.tw/StockInfo/StockList.asp?MARKET_CAT=%E8%87%AA%E8%A8%82%E7%AF%A9%E9%81%B8&INDUSTRY_CAT=%E6%88%91%E7%9A%84%E6%A2%9D%E4%BB%B6&FL_ITEM0=%E9%80%A3%E7%BA%8C%E9%85%8D%E7%99%BC%E5%90%88%E8%A8%88%E8%82%A1%E5%88%A9%E6%AC%A1%E6%95%B8&FL_VAL_S0=7&FL_VAL_E0=&FL_ITEM1=%E7%B4%AF%E5%AD%A3%E2%80%93EPS%E5%B9%B4%E6%88%90%E9%95%B7%E7%8E%87%28%25%29&FL_VAL_S1=0&FL_VAL_E1=&FL_ITEM2=&FL_VAL_S2=&FL_VAL_E2=&FL_ITEM3=&FL_VAL_S3=&FL_VAL_E3=&FL_ITEM4=&FL_VAL_S4=&FL_VAL_E4=&FL_ITEM5=&FL_VAL_S5=&FL_VAL_E5=&FL_ITEM6=&FL_VAL_S6=&FL_VAL_E6=&FL_ITEM7=&FL_VAL_S7=&FL_VAL_E7=&FL_ITEM8=&FL_VAL_S8=&FL_VAL_E8=&FL_ITEM9=&FL_VAL_S9=&FL_VAL_E9=&FL_ITEM10=&FL_VAL_S10=&FL_VAL_E10=&FL_ITEM11=&FL_VAL_S11=&FL_VAL_E11=&FL_RULE0=&FL_RULE1=&FL_RULE2=&FL_RULE3=&FL_RULE4=&FL_RULE5=&FL_RANK0=&FL_RANK1=&FL_RANK2=&FL_RANK3=&FL_RANK4=&FL_RANK5=&FL_FD0=&FL_FD1=&FL_FD2=&FL_FD3=&FL_FD4=&FL_FD5=&FL_SHEET=%E5%AD%A3%E7%B4%AF%E8%A8%88%E7%8D%B2%E5%88%A9%E8%83%BD%E5%8A%9B&FL_SHEET2=%E7%8D%B2%E5%88%A9%E8%83%BD%E5%8A%9B&FL_MARKET=%E4%B8%8A%E5%B8%82%2F%E4%B8%8A%E6%AB%83&FL_QRY=%E6%9F%A5++%E8%A9%A2
------------------------------------------------------------------------------------------------------
另外想問一下~

如何寫法可以直接抓到這樣~
不用在去刪減多餘資料?
或是有那一樓有詳細的寫法?
Snare大,
終於又可以了,謝謝你,前面幾個你已經說了,我還問,真是有夠笨,這次我真學會post和get的用法,真心感謝你!
機八陽 wrote:
可以把程式寫成只這樣只抓這部分~
而不是全部網頁的都抓下來嗎?



.........
.........
.........
Loop
.document.all("FL_QRY").Click

Application.Wait (Now + TimeValue("00:00:30"))

Set Table = .Document.getelementsbytagname("table")(107).Rows

For i = 0 To Table.Length - 1
For j = 0 To Table(i).Cells.Length - 1
ActiveSheet.Cells(i + 1, j + 1) = Table(i).Cells(j).innertext
Next j
Next i

If Err.Number <> 0 Th ..................
.........
.........
.........





機八陽 wrote:
後來我換了程式寫法~這一個是有抓到~

但一樣會顯示空白~
現在要進入頁面後按查詢才能~


'請參考828樓範例
'POST 改成 GET
'取消 do .... loop 迴圈,取消 if i=0 ........
'IIf(j = 1 …… 改成 IIf(j = 0 ……

Url = "https://goodinfo.tw/StockInfo/StockList.asp?MARKET_CAT=自訂篩選&INDUSTRY_CAT=我的條件&FL_ITEM0=連續配發合計股利次數&FL_VAL_S0=7&FL_VAL_E0=&FL_ITEM1=累季–EPS年成長率(%)&FL_VAL_S1=0&FL_VAL_E1=&FL_ITEM2=&FL_VAL_S2=&FL_VAL_E2=&FL_ITEM3=&FL_VAL_S3=&FL_VAL_E3=&FL_ITEM4=&FL_VAL_S4=&FL_VAL_E4=&FL_ITEM5=&FL_VAL_S5=&FL_VAL_E5=&FL_ITEM6=&FL_VAL_S6=&FL_VAL_E6=&FL_ITEM7=&FL_VAL_S7=&FL_VAL_E7=&FL_ITEM8=&FL_VAL_S8=&FL_VAL_E8=&FL_ITEM9=&FL_VAL_S9=&FL_VAL_E9=&FL_ITEM10=&FL_VAL_S10=&FL_VAL_E10=&FL_ITEM11=&FL_VAL_S11=&FL_VAL_E11=&FL_RULE0=&FL_RULE1=&FL_RULE2=&FL_RULE3=&FL_RULE4=&FL_RULE5=&FL_RANK0=&FL_RANK1=&FL_RANK2=&FL_RANK3=&FL_RANK4=&FL_RANK5=&FL_FD0=&FL_FD1=&FL_FD2=&FL_FD3=&FL_FD4=&FL_FD5=&FL_SHEET=季累計獲利能力&FL_SHEET2=獲利能力&FL_MARKET=上市/上櫃&FL_QRY=查 詢"

Url_a = Url

https://tw.stock.yahoo.com改版,大部份的資料都改成json格式
這方面 finance.yahoo.com 的部份網頁,也是相同格式
例如:https://finance.yahoo.com/quote/AAPL/financials?p=AAPL
但不確定是什麼時候改版,因為上次寫finance範例是2017年


範例網址
https://tw.stock.yahoo.com/rank/volume
當日行情=>成交量排行=>即時行情排行

裡面的18(6x3)頁資料
成交量、漲幅、跌幅、價差、成交價、成交金額
(合併、上市、上櫃)




雖然18頁資料,各有不同的網址,不理json用剪貼薄解決也行
但是會出現一個問題,資料全部是正數,不知是正還是負
因為yahoo用圖案代替正負號,使得漲跌無法複製
所以還是需要靠解析json 才行

這邊要注意的是,json資料,是混在網頁原始碼裡面
json 資料都放在原始碼中root.App.main 後面
(但目前是改版時期,也許一段時間後,會有獨立的json網址可用)




需先從.responsetext,分類出來,還原成格式標準的純json資料
才能用程式碼做解析,不然就要改用regexp來拆解文字,很麻煩的





'程式碼放module(模組)裡,執行main()副程式
'因語法衝突,部份程式碼無法顯示,改用圖片代替文字,或請直接看附檔
'空白活頁薄需先手動建立18個工作表(名稱如下)
'volume_ALL、volume_TAI、volume_TWO、change-up_ALL、change-up_TAI、change-up_TWO'
'change-down_ALL、change-down_TAI、change-down_TWO
'day-range_ALL、day-range_TAI、day-range_TWO
'price_ALL、price_TAI、price_TWO、turnover_ALL、turnover_TAI、turnover_TWO
'(名稱可自行修改,但程式碼也需做適當的修改)


Sub main()

Dim i As Integer, j As Integer, Url As String, sheet_name As String, urla(), urlb()


'當日行情/成交量排行/即時行情排行
'================================

'成交量(volume)、漲幅(change-up)、跌幅(change-down)、價差(day-range)、成交價(price)、成交金額(turnover)
urla = Array("volume", "change-up", "change-down", "day-range", "price", "turnover")

'合併(ALL)、上市(TAI)、上櫃(TWO")
urlb = Array("ALL", "TAI", "TWO")

Application.ScreenUpdating = False

For i = 0 To 5

For j = 0 To 2

Url = "https://tw.stock.yahoo.com/rank/" & urla(i) & "?exchange=" & urlb(j)
sheet_name = urla(i) & "_" & urlb(j)

If checksheet(sheet_name) = True Then
Call GET_Yahoo_TW_Rank(Url, sheet_name)
Else
Debug.Print sheet_name & " ???"
End If

'Delaytick (0.5)
Next j

Next i


Application.ScreenUpdating = True

'Sheets("volume_ALL").Select

MsgBox "ok", vbOKOnly, "Report"

End Sub



Sub GET_Yahoo_TW_Rank(Url As String, sheet_name As String)

Dim Xmlhttp As Object, Jsondata As Object, DecodeJson, RankData, temp, i As Integer, ttt As Double

Set Jsondata = CreateObject("HtmlFile")
Set Xmlhttp = CreateObject("WinHttp.WinHttpRequest.5.1")




ttt = Timer

With Xmlhttp

.Open "GET", Url, False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.setRequestHeader "Cache-Control", "no-cache"
.setRequestHeader "Pragma", "no-cache"
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
.send

End With


temp = "{" & Split(Split(Xmlhttp.responsetext, "{""exchange"":""" & Right(sheet_name, 3) & """}}},")(1), ",""pagination"":{""resultsTotal")(0) & "}}}"

Set DecodeJson = Jsondata.JsonParse(temp)
Set RankData = CallByName(CallByName(CallByName(DecodeJson, "TableStore", VbGet), "main-0-StockRanking", VbGet), "list", VbGet)


With Sheets(sheet_name)

.Cells.Clear
.Range("a3:k3") = Array("名次", "股名", "股號", "成交價", "漲跌", "漲跌幅(%)", "最高", "最低", "價差", "成交量(張)", "成交值(億)")

'點我看大圖(20210916修正2行程式碼,請自行修改附件)


'range("c1") 改成下面這行
.Range("b2") = Replace(Split(CallByName(CallByName(CallByName(CallByName(DecodeJson, "TableStore", VbGet), "main-0-StockRanking", VbGet), "listMeta", VbGet), "rankTime", VbGet), "+")(0), "T", " ")


For i = 0 To 99
Set temp = CallByName(RankData, i, VbGet)
'debug '.Cells(I + 4, 1) = I + 1 & "(" & CallByName(temp, "rank", VbGet) & ")"
.Cells(i + 4, 1) = i + 1
.Cells(i + 4, 2) = temp.symbolName
.Cells(i + 4, 3) = CallByName(temp, "symbol", VbGet)
.Cells(i + 4, 4) = CallByName(temp, "price", VbGet)
.Cells(i + 4, 5) = CallByName(temp, "change", VbGet)
.Cells(i + 4, 6) = "'" & temp.changePercent

If .Cells(i + 4, 5) <> 0 Then
.Range("d" & i + 4 & ":f" & i + 4).Font.Color = IIf(.Cells(i + 4, 5) < 0, RGB(0, 171, 94), RGB(255, 51, 58))
If .Cells(i + 4, 5) < 0 Then
.Cells(i + 4, 5) = Replace(.Cells(i + 4, 5), "-", "▼")
.Cells(i + 4, 6) = Replace(.Cells(i + 4, 6), "-", "▼")
Else
.Cells(i + 4, 5) = "▲" & .Cells(i + 4, 5)
.Cells(i + 4, 6) = Replace(.Cells(i + 4, 6), "+", "▲")
End If
End If


.Cells(i + 4, 7) = temp.dayHigh
.Cells(i + 4, 8) = temp.dayLow
.Cells(i + 4, 9) = temp.dayHighLowDiff
.Cells(i + 4, 10) = temp.volK
'debug '.Cells(i + 4, 11) = temp.turnoverK / 100000 & "(" & temp.turnoverK & ")"
.Cells(i + 4, 11) = temp.turnoverK / 100000
Next i

.Range("K4:k103").NumberFormatLocal = "0.0000_ "
.Range("j4:J103").NumberFormatLocal = "#,##0_ "
.Range("d4:f103").Font.Bold = True
.Cells.EntireColumn.AutoFit

End With

Debug.Print sheet_name & "=" & Timer - ttt & "s"

Set Xmlhttp = Nothing
Set Jsondata = Nothing
Set DecodeJson = Nothing
Set RankData = Nothing
Set temp = Nothing

End Sub


Sub Delaytick(setdelay As Single)

Dim StartTime As Double, NowTime As Double
StartTime = Timer * 100
setdelay = setdelay * 100
Do
NowTime = Timer * 100
DoEvents
Loop Until NowTime - StartTime > setdelay

End Sub




Function checksheet(sheet_name As String) As Boolean
Dim check As Range
On Error Resume Next
Set check = ThisWorkbook.Sheets(sheet_name).Range("a1")
If Err.Number <> 0 Then checksheet = False Else checksheet = True
On Error GoTo 0
End Function







補充:忘了這是即時資料,有資料更新時間比較方便
(是網頁資料更新時間,不是資料下載時間)




.Range("c1") = Left... ... ... ... 那行程式碼,可修改如下,有需要請自行修改附件
        .Range("b2") = Replace(Split(CallByName(CallByName(CallByName(CallByName(DecodeJson, "TableStore", VbGet), "main-0-StockRanking", VbGet), "listMeta", VbGet), "rankTime", VbGet), "+")(0), "T", "  ")


(20190916,網頁改版)
=> range("c1")同上
=> range("b2"),請看程式碼內修正後圖片


[點擊下載]
網頁TABLE爬蟲解析工具(Excel VBA)

此檔案是 網頁 TABLE 格式 爬蟲範例.
全部程式碼也不會很長。

基本上只要是 TABLE 格式的資料,都可以用這範例為基礎去修改。
有些網站在爬蟲時需要帶入 Referer、User-Agent 等資料。

這些在這個範例檔案裏面都有程式碼可以參考。

https://drive.google.com/file/d/1GAKGtQ3iCzLdjo9zmTlqjlVL0tkrEp3I/view?usp=sharing


要抓 json 資料的話,此範例不適用。
snare wrote:
(***此文只在mobile01...(恕刪)



師傅 這兩天yahoo的是不是有改版動過?
無法更新惹
bioleon69 wrote:
這兩天yahoo的是不是有改版動過?
無法更新惹


1000樓+1024樓,yahoo下載範例,測試正常
(測試時間2021-06-11 21:10)

mickmini wrote:
網頁TABLE爬蟲解析工具(Excel VBA)
此檔案是 網頁 TABLE 格式 爬蟲範例.


謝謝您分享自己的作品,我看完程式碼了
寫的很讚、簡潔、說明詳細

轉碼部份,也可改用(請參考877樓)
.Charset = "_autodetect_all"
版大 , 因原使用網頁改版 , 目前解析不出來 URL + request ,
使用 "網頁table爬蟲解析工具" , 只有網頁標題內容 , 卻沒有內容被轉出來 ,
原本有 cvs 下載格式 , 已於 6/3 關閉了 ,
要請版大協助解決 , 如下是騰訊的收盤價 , 想要把它全部轉出來使用 , 謝謝 !!

https://stockapp.finance.qq.com/mstats/#mod=list&id=ssa&module=SS&type=ranka
oliwa wrote:
版大 , 因原使用網(恕刪)


這個網址回傳的資料不是 HTML TABLE 的格式。

它是經由這個網址再回傳資料內容。

https://qt.gtimg.cn/q=sh688700,sh603529,sh605259,sz300134,sz300076,sz300649,sz300235,sh688579,sz300349,sz300264,sz300581,sz300077,sz300560,sz300393,sz300530,sz300663,sh688022,sz300319,sh688127,sz300389,sz300397,sh688027,sh688018,sz300350,sz300635&r=51396731
關閉廣告
文章分享
評分
評分
複製連結
請輸入您要前往的頁數(1 ~ 144)

今日熱門文章 網友點擊推薦!