上一個寫法比較吃電腦資源且速度比較慢~
後來我換了程式寫法~這一個是有抓到~
但一樣會顯示空白~
現在要進入頁面後按查詢才能~
要怎麼改程式碼才行呢?
沒有按查詢所以無法顯示出來
--------------------------------------------------------------------------------------------------------
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
------------------------------------------------------------------------------------------------------
另外想問一下~
如何寫法可以直接抓到這樣~
不用在去刪減多餘資料?
或是有那一樓有詳細的寫法?
機八陽 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
這方面 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 格式 爬蟲範例.
全部程式碼也不會很長。
基本上只要是 TABLE 格式的資料,都可以用這範例為基礎去修改。
有些網站在爬蟲時需要帶入 Referer、User-Agent 等資料。
這些在這個範例檔案裏面都有程式碼可以參考。
https://drive.google.com/file/d/1GAKGtQ3iCzLdjo9zmTlqjlVL0tkrEp3I/view?usp=sharing
要抓 json 資料的話,此範例不適用。
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
關閉廣告