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

inspireme543 wrote:
1) Chrome + 開啟 Javascript

- 網頁:A區 的內容有顯示
- 網頁原始碼 ( view-source:https...),並沒有看到 A區 相關的內容


inspireme543 wrote:
3) 使用 Chrome 的開發人員工具 -> Network -> Fetch / XHR

- Reload 頁面,發現 eqc.js。
- 故意 Block eqc.js 會造成 A區內容不顯示。
- 但是,Preview eqp.js 並非 json 之類的資料,也看不到跟 A 區相關的內容
- 找不到 A區的主要封包...



資料就在網頁原始碼裡面,是json格式,找不到是因為那是未計算的原始資料
要處理需先拆出來,可參考1102樓





inspireme543 wrote:
2) Chrome + 關掉 Javascript
- 網頁:A區 的內容沒有顯示
- 應該是由 js 另外產生 A區內容


是的,但我不知道json裡面的項目,分別是代表那個資料
散戶、大戶,是計算出來的,我也不知道是用那個去加加減減
只知道e10=總張數





Sub get_agdstock()

Dim Xmlhttp As Object, Jsondata As Object, DecodeJson, temp, URL As String, ttt As Double

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






ttt = Timer

URL = "https://agdstock.club/eqc/2330-台積電"

With Xmlhttp
.Open "GET", URL, False
.setRequestHeader "Cache-Control", "no-cache"
.setRequestHeader "Pragma", "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

Set DecodeJson = Jsondata.JsonParse(Split(Split(.responsetext, "eqData = JSON.parse('")(1), "');" & Chr(10) & " const eqcDom")(0))

End With


Set temp = CallByName(DecodeJson, "2022-11-25", VbGet)

MsgBox Round(CallByName(temp, "e10", VbGet) / 1000, 0) & "張"


Debug.Print Timer - ttt

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


End Sub




json處理方式,除了一個一個用callbyname取出之外
也可以參考1168樓、1171樓,全部取出的方式



'原始碼裡面,還有另一份股票代號+名稱的json資料

………
………
………
Set DecodeJson = Jsondata.JsonParse(Split(Split(.responsetext, "var src = JSON.parse('")(1), "');" & Chr(10))(0))
………
………
………




inspireme543
1168樓 https://www.mobile01.com/topicdetail.php?f=511&t=4737630&p=117#83749404
inspireme543
1171樓 https://www.mobile01.com/topicdetail.php?f=511&t=4737630&p=118#83800653
無聊看了一下計算方式,修正1281樓範例


'C、D、E、F欄,單位自行換算
'E、F欄,請自行加程式或公式處理,e2=c2-c3、e3=c3-c4... ... f2=d2-d3、f3=d3-d4... ...




Sub get_agdstock()

Dim Xmlhttp As Object, Jsondata As Object, DecodeJson, temp, item, value, total As Double, URL As String, i As Integer, j As Integer, ttt As Double

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


'以下4行是圖片,請手動輸入



Sheets("工作表1").Cells.Clear
Sheets("工作表1").Range("a1:d1") = Array("日期", "總張數", "散戶", "大戶")
ttt = Timer

URL = "https://agdstock.club/eqc/2330-台積電"

With Xmlhttp
.Open "GET", URL, False
.setRequestHeader "Cache-Control", "no-cache"
.setRequestHeader "Pragma", "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

Set DecodeJson = Jsondata.JsonParse(Split(Split(.responsetext, "eqData = JSON.parse('")(1), "');" & Chr(10) & " const eqcDom")(0))

'stockname+id
'Set DecodeJson = Jsondata.JsonParse(Split(Split(.responsetext, "var src = JSON.parse('")(1), "');" & Chr(10))(0))


End With

Set temp = Jsondata.GetKeys(DecodeJson)
item = Split(temp, ",")

For i = 0 To UBound(item)

Sheets("工作表1").Cells(i + 2, 1) = item(i)
Set value = CallByName(DecodeJson, item(i), VbGet)

Sheets("工作表1").Cells(i + 2, 2) = Round(CallByName(value, "e10", VbGet) / 1000, 0) & "張"

total = 0
For j = 1 To 5
total = total + CallByName(value, "e" & j, VbGet)
Next j
Sheets("工作表1").Cells(i + 2, 3) = total

total = 0
For j = 6 To 9
total = total + CallByName(value, "e" & j, VbGet)
Next j
Sheets("工作表1").Cells(i + 2, 4) = total

Next i


Debug.Print Timer - ttt

Set Xmlhttp = Nothing
Set Jsondata = Nothing
Set DecodeJson = Nothing
Set temp = Nothing
Set value = Nothing


End Sub


inspireme543
感謝大神~ 我照著您的程式碼,有將資料抓出來了,顯然新手的我還有很多需要學習的地方,謝謝您願意無私的教導及分享。
請問高手
最近 yahoo finance 又不能抓了,用了版主的寫的程式
卡在下面這一句出現錯誤 "超出索引範圍""請問有辦法解決嗎 謝謝
Crumbkey = Left(Split(.responsetext, """Cr mbStore"":{""crumb"":""")(1), 11)
snare
直接把那行程式碼刪掉就行,其它不變,yahoo finance某次改版後就不需要用到crumbkey來檢查。
請問為什麼沒辦法切換頁面
thePage = html.all("selRANK").Options.Length - 1 '取得總頁數
For p = 1 To thePage '總頁數

Set mySelect = html.all("selRANK")
mySelect.Focus '不確定是否必須
mySelect.selectedIndex = p '選擇第幾頁
mySelect.FireEvent "onchange" '改變顯示頁面時,觸發事件(event)去執行網頁上的JavaScript

'等待網頁資料完全載入(對AJAX取得資料的方式應該無效)
Do While .Busy Or .readyState <> READYSTATE_COMPLETE: DoEvents: Loop

'等待網頁資料完全載入(AJAX)
Call delay(20) '依個人網路速度資料來源伺服器狀況調整

bank87012
版主寫的828程式碼
snare
雖然您問的程式碼,不是我828樓寫的範例,不過因為您的發問,我才發現網頁改版,範例已修正,有需要請去828樓看文章。
bank87012 wrote:
版主寫的828程式碼


bank87012 wrote:
mySelect.selectedIndex = p '選擇第幾頁
mySelect.FireEvent "onchange" '改變顯示頁面時,觸發事件(event)去執行網頁上的JavaScript

'等待網頁資料完全載入(對AJAX取得資料的方式應該無效)
Do While .Busy Or .readyState <> READYSTATE_COMPLETE: DoEvents: Loop


您1285樓問的,不是我828樓(2020/7/13)寫的範例

不過因為您的發問,我回頭重新測試了一下828樓
才發現原來網頁又改版,下載網址變了,原網址無法下載

(20230122)已修正範例,有需要的,請回828樓下載

換網址後,原程式不動,雖可正常下載,但需加上更多的延遲時間
我試幾次就被鎖了,鎖一次好像30分鐘以上
有空我再試試,要加長多久才不容易被鎖







snare wrote:
既然 finance...(恕刪)


祝師傅新年快樂 萬事如意 !!!
也預祝此棟的大家新年快樂啦!!

回到主題
年假回來挖寶一下師傅分享的各種程式
(272樓)
yahoo finance
如果放了上市櫃的所有股票清單一次下載(1800檔左右)
會出error
小弟的無腦方法是
找迴圈結束的地方加入delay

If i Mod 30 = 0 Then
Application.Wait Now + TimeValue("0:00:07")
end if

已測試完是可以跑出無error 1800檔全部跑完~
snare
感謝您幫忙測試,沒想到5年多前寫的古董範例,還能正常執行。
版大您好,
目前在下載營收資料時遇到下載的資料黏在一起的窘境,
資料又無特殊字元或空格可以使用split的方式進行切割,
且資料在寫入儲存格時 儲存格的分行又與原始資料不同,
功力太淺 被考倒了,
是否能稍微指點一下小弟,
謝謝~



[點擊下載]
strainny wrote:
目前在下載營收資料時遇到下載的資料黏在一起的窘境


方法很多,比較簡單一點的,可以利用剪貼薄方式處理
您檔案中的,function 資料下載ByXmlHttp,改用剪貼薄的簡易寫法如下





Function 資料下載ByXmlHttp(LinkID As String, TabRow As Integer)

Dim URL, HTMLsourcecode, GetXml
Dim Table
Dim i, j, k As Integer
Dim temp
Dim Clipboard As Object

Sheets("tmp").Cells.Clear

DoEvents
Set HTMLsourcecode = CreateObject("htmlfile")
Set GetXml = CreateObject("msxml2.xmlhttp")
Set Clipboard = CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")

URL = LinkID

With GetXml
.Open "GET", URL, False
.setRequestHeader "Cache-Control", "no-cache"
.setRequestHeader "Pragma", "no-cache"
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
.send

HTMLsourcecode.body[removed] = convertraw(.ResponseBody)
Set Table = HTMLsourcecode.all.tags("table")(TabRow)

Clipboard.settext Table[removed]
Clipboard.putinclipboard

Sheets("tmp").Cells(1, 1).Select
Sheets("tmp").PasteSpecial NoHTMLFormatting:=True
End With

Set Clipboard = Nothing
Set HTMLsourcecode = Nothing
Set GetXml = Nothing

End Function

'因語法衝突,請自行把[removed]改成 .(小數點)innerhtml
'詳細請看圖對照修改



snare wrote:
方法很多,比較簡單一...(恕刪)


S版大您好,
很神奇的 原始檔測試OK,
但將他整理至我的excel下會發生下下問題點: (1)一個是PasteSpecial的錯誤 (2)一個是很低的機率下sheets("tmp").cells(1,1)內容會出現兩個方框





嘗試回去尋找Clipboard內容 當下是無變數的

再回到Table.innerhtml看,我就看不懂了
(另外請教一下 為何不是抓取Table.innerText的資料)





又試著試著似乎在刪除工作表1後,
程式又可以下載了?!
可以請S大幫忙解惑一下嗎,謝謝~






[點擊下載]



另外想了解一下一開始的問題,
是在怎樣原因下會有儲存格資料黏在一起的問題發生,
S大您的寫法又好高深 看不懂是怎麼一個破解方法
謝謝~
關閉廣告
文章分享
評分
評分
複製連結
請輸入您要前往的頁數(1 ~ 156)

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