2018年10月13日 星期六

用XMLHttpRequest法抓取網頁資料


這個解釋一下好了
一、msxml2.xmlhttp 我的範例是為了讓超過5筆資料能稍微抓快一點所寫的
如果只抓一個網頁,不管美觀,其實程式很短的
'========================================================
Sub getstock()
Dim URL, HTMLsourcecode,GetXml
Set HTMLsourcecode = CreateObject("htmlfile")
Set GetXml=CreateObject("msxml2.xmlhttp")
URL = "https://tw.stock.yahoo.com/q/q?s=2412"
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.innerhtml = .responsetext
Set Table = HTMLsourcecode.all.tags("table")(6).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
End With
Set HTMLsourcecode = Nothing
Set GetXml = Nothing
End Sub
'==========================================================
以下程式同上,這是說明用的
'========================================================
Sub getstock()
Dim URL, HTMLsourcecode,GetXml
Set HTMLsourcecode = CreateObject("htmlfile")
Set GetXml=CreateObject("msxml2.xmlhttp")
'範例網址yahoo 中華電信 股價
URL = "https://tw.stock.yahoo.com/q/q?s=2412"

With GetXml
.Open "GET", URL, False
'以下這3行避免抓到暫存資料
.setRequestHeader "Cache-Control", "no-cache"
.setRequestHeader "Pragma", "no-cache"
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
.send


'把傳回值轉成標準htmlfile,這裡就要解釋一下了
HTMLsourcecode.body.innerhtml = .responsetext
'.responsetext 傳回值如下
'要從這些文字中找出資料,要用一堆搜尋、判斷,程式會變的很長

Debug.Print .responsetext
'但如果轉成標準htmlfile,就很簡單了
'可以用tags方法,很容易的取出網頁中的某個物件,程式變短
'這裡是取出表格編號6,tags("table")(6),'看網頁原始碼就可以知道是那一個表格
'如果不會看,很簡單,從0開始試
'如果只是要取出表格,基本上這個範例幾乎所有非java網頁都適用

Debug.Print HTMLsourcecode.body.innerhtml


Set Table = HTMLsourcecode.all.tags("table")(6).Rows
'把要的表格轉成一個table陣列


'table.length 算出表格有幾列
For i = 0 To Table.Length - 1
'table(i).cells.length 算出每列表格有幾欄
For j = 0 To Table(i).Cells.Length - 1
'把每格資料照順序填入工作表中
'這裡是用比較簡單的寫法,缺點是比較慢
'如果要快一點,需用陣列一次寫入全部資料
'使用方式請參考1樓、45樓、71樓、107樓的程式碼改寫
ActiveSheet.Cells(i + 1, j + 1) = Table(i).Cells(j).innertext
Next j
Next i
End With
'釋放記憶體
Set HTMLsourcecode = Nothing
Set GetXml = Nothing
End Sub

'==========================================================
二、internetexplorer.application
這個通常是用來ie自動化用的
輸入帳號、密碼、下一頁、上一頁、重新整理、點網頁上的按鈕…等等的
雖然抓資料也可以,但不建議,超級慢

範例,自動打帳號密碼後按送出
'==========================================================
Sub test()

Dim IE As Object
Set IE = CreateObject("internetexplorer.application")
IE.Visible = True
IE.navigate "https://login.yahoo.com/config/mail?&.src=ym&.intl=tw"

Do While IE.busy Or IE.readystate < 4
DoEvents
Loop

IE.document.all.Item("login-username").Value = "您的email"
IE.document.all.Item("login-passwd").Value = "您的密碼"
IE.document.forms(0).submit
Set IE = Nothing

End Sub
'==========================================================
以下程式碼同上,說明用
'==========================================================
Sub test()

Dim IE As Object
Set IE = CreateObject("internetexplorer.application")
IE.Visible = True
'範例網站yahoo首頁登入
IE.navigate "https://login.yahoo.com/config/mail?&.src=ym&.intl=tw"

'等網頁載入
Do While IE.busy Or IE.readystate < 4
DoEvents
Loop

'設帳號、密碼後,按送出
'不過 "login-username","login-passwd",forms(0),不是每個網站都一樣
'看開發者喜好設定的,所以只要換網站,就要看原始碼,找出名稱
IE.document.all.Item("login-username").Value = "您的email"
IE.document.all.Item("login-passwd").Value = "您的密碼"
IE.document.forms(0).submit
Set IE = Nothing

End Sub
'==========================================================
但是現在大部份要登入的網站,都用2步驟驗證了
也沒辦法完全自動化了,還是需要人工輸入


來源:
https://www.mobile01.com/topicdetail.php?f=511&t=4737630&p=3

原文標題:
使用VBA解決 excel web 查詢無法匯入、匯入太慢的股市資料
https://www.mobile01.com/topicdetail.php?f=511&t=4737630&p=1

2 則留言:

  1. 感謝您轉貼,並且尊重我的文章,有附上來源網址

    不過我希望網址改成第一頁,因為有整理好的標題,比較方便閱讀(如下)
    https://www.mobile01.com/topicdetail.php?f=511&t=4737630&p=1

    回覆刪除
    回覆
    1. 十分感謝你在網路上的分享,讓沒有程式基礎的人,在漫漫網海上能看到曙光!

      刪除