2017-04-03 131 views
1

我一直在嘗試刮掉整個整個 HTML主體並將其分配爲字符串變量,然後再處理該字符串以填充excel文件 - 這將在一個循環中完成以更新日期每隔5分鐘一次。使用VBA刮掉AJAX頁面

這些頁面是AJAX頁面,所以運行看起來像JavaScript的東西(儘管我並不熟悉JS)。

我使用XMLHttpRequest對象(下面的代碼)嘗試,但牛逼返回JS調用:

Set XMLHTTP = CreateObject("MSXML2.serverXMLHTTP") 
XMLHTTP.Open "GET", "https://www.google.co.uk/finance?ei=bQ_iWLnjOoS_UeWcqsgE", False 
XMLHTTP.setRequestHeader "Content-Type", "text/xml" 
XMLHTTP.send 
Debug.Print XMLHTTP.ResponseText 

我試圖創建一個與下面的代碼,但同樣的IE對象,同樣的問題:

Set IE = CreateObject("InternetExplorer.Application") 
IE.Visible = False 
IE.navigate "https://www.google.co.uk/finance?ei=bQ_iWLnjOoS_UeWcqsgE" 
While IE.Busy Or IE.ReadyState <> 4: DoEvents: Wend 
Set HTMLdoc = IE.Document 
Debug.Print = HTMLdoc.Body.innerHTML 

我想什麼它提供給我時,我打F12和到了檢查標籤準確的文本(即低於黃色區域內的文本的全部。) - 如果我能得到這個(全擴展的)我可以從那裏工作。任何幫助將大規模讚賞。

enter image description here

在上面的例子中(谷歌財經),該指數價格異步更新 - 我想在在我指定的字符串時捕捉到這些。

+0

請問您可以添加到您的問題的預期產出?目前尚不清楚開發人員工具中提供的文字是什麼。 – omegastripes

+0

@omegastripes我已經包括了最後一句 - 如果我正在尋找CAC 40(法國證券交易所)價值,我目前無法提取它,因爲它不包含在'Debug.print'中。 – Jeremy

回答

1

您剛纔檢查XHR時的網頁呢,查找包含相關數據的人,做出同樣XHR(無論是網站提供API或沒有)和解析響應的任何動態加載的數據,或者在IE自動化的情況下,你添加額外的等待循環,直到目標元素變爲可訪問,然後從DOM中檢索它。

在這種情況下,您可以通過Google Finance API獲取數據。

方法1.

爲了讓你必須知道股票代碼,這可能會網頁的HTML內容或電子郵件中輕鬆找到所求。 G。如果您點擊CAC 40,在打開的頁面中會出現CAC 40(INDEXEURO:PX1)的標題。

有一些頁面上的以下股票和股票交換符號在世界市場表:

Shanghai   SHA:000001 
S&P 500    INDEXSP:.INX 
Nikkei 225   INDEXNIKKEI:NI225 
Hang Seng Index  INDEXHANGSENG:HSI 
TSEC    TPE:TAIEX 
EURO STOXX 50  INDEXSTOXX:SX5E 
CAC 40    INDEXEURO:PX1 
S&P TSX    INDEXTSI:OSPTX 
S&P/ASX 200   INDEXASX:XJO 
BSE Sensex   INDEXBOM:SENSEX 
SMI     INDEXSWX:SMI 
ATX     INDEXVIE:ATX 
IBOVESPA   INDEXBVMF:IBOV 
SET     INDEXBKK:SET 
BIST100    INDEXIST:XU100 
IBEX    INDEXBME:IB 
WIG     WSE:WIG 
TASI    TADAWUL:TASI 
MERVAL    BCBA:IAR 
IPC     INDEXBMV:ME 
IDX Composite  IDX:COMPOSITE 

將它放到網址:

http://finance.google.com/finance/info?q=SHA:000001,INDEXSP:.INX,INDEXNIKKEI:NI225,INDEXHANGSENG:HSI,TPE:TAIEX,INDEXSTOXX:SX5E,INDEXEURO:PX1,INDEXTSI:OSPTX,INDEXASX:XJO,INDEXBOM:SENSEX,INDEXSWX:SMI,INDEXVIE:ATX,INDEXBVMF:IBOV,INDEXBKK:SET,INDEXIST:XU100,INDEXBME:IB,WSE:WIG,TADAWUL:TASI,BCBA:IAR,INDEXBMV:ME,IDX:COMPOSITE

響應包含JSON數據,如此:

[ 
    { 
     "id": "7521596", 
     "t": "000001", 
     "e": "SHA", 
     "l": "3,222.51", 
     "l_fix": "3222.51", 
     "l_cur": "CN¥3,222.51", 
     "s": "0", 
     "ltt": "3:01PM GMT+8", 
     "lt": "Mar 31, 3:01PM GMT+8", 
     "lt_dts": "2017-03-31T15:01:15Z", 
     "c": "+12.28", 
     "c_fix": "12.28", 
     "cp": "0.38", 
     "cp_fix": "0.38", 
     "ccol": "chg", 
     "pcls_fix": "3210.2368" 
    }, 
    ... 
] 

您可以使用下面的VBA代碼來解析響應和輸出結果。它需要將JSON.bas模塊導入到VBA項目以進行JSON處理。

Sub GoogleFinanceData() 

    Dim sJSONString As String 
    Dim vJSON As Variant 
    Dim sState As String 
    Dim aData() 
    Dim aHeader() 

    ' Retrieve Google Finance data 
    With CreateObject("MSXML2.XMLHTTP") 
     .Open "GET", "http://finance.google.com/finance/info?q=SHA:000001,INDEXSP:.INX,INDEXNIKKEI:NI225,INDEXHANGSENG:HSI,TPE:TAIEX,INDEXSTOXX:SX5E,INDEXEURO:PX1,INDEXTSI:OSPTX,INDEXASX:XJO,INDEXBOM:SENSEX,INDEXSWX:SMI,INDEXVIE:ATX,INDEXBVMF:IBOV,INDEXBKK:SET,INDEXIST:XU100,INDEXBME:IB,WSE:WIG,TADAWUL:TASI,BCBA:IAR,INDEXBMV:ME,IDX:COMPOSITE", False 
     .Send 
     If .Status <> 200 Then Exit Sub 
     sJSONString = .responseText 
    End With 
    ' Trim extraneous chars 
    sJSONString = Mid(sJSONString, InStr(sJSONString, "[")) 
    ' Parse JSON string 
    JSON.Parse sJSONString, vJSON, sState 
    If sState = "Error" Then Exit Sub 
    ' Convert to table format 
    JSON.ToArray vJSON, aData, aHeader 
    ' Results output 
    With Sheets(1) 
     .Cells.Delete 
     .Cells.WrapText = False 
     If UBound(aHeader) >= 0 Then OutputArray .Cells(1, 1), aHeader 
     Output2DArray .Cells(2, 1), aData 
     .Columns.AutoFit 
    End With 

End Sub 

Sub OutputArray(oDstRng As Range, aCells As Variant) 

    With oDstRng 
     .Parent.Select 
     With .Resize(1, UBound(aCells) - LBound(aCells) + 1) 
      .NumberFormat = "@" 
      .Value = aCells 
     End With 
    End With 

End Sub 

Sub Output2DArray(oDstRng As Range, aCells As Variant) 

    With oDstRng 
     .Parent.Select 
     With .Resize(_ 
       UBound(aCells, 1) - LBound(aCells, 1) + 1, _ 
       UBound(aCells, 2) - LBound(aCells, 2) + 1) 
      .NumberFormat = "@" 
      .Value = aCells 
     End With 
    End With 

End Sub 

正如你所需要的數據位於l_fixc_fixcp_fix列的結果。方法2。

您也可以由URL使XHR這樣一個用於CAC 40:

https://www.google.co.uk/finance/getprices?q=PX1&x=INDEXEURO&i=120&p=20m&f=d,c,v,o,h,l

特別是URL是PX1股票和INDEXEURO證券交易所的符號,120秒的時間間隔在20分鐘期間,響應數據d,c,v,o,h,l用於DATE(UNIX TimeStamp),CLOSE,VOLUME,OPEN,HIGH,LOW。

響應格式如下:

EXCHANGE%3DINDEXEURO 
MARKET_OPEN_MINUTE=540 
MARKET_CLOSE_MINUTE=1050 
INTERVAL=120 
COLUMNS=DATE,CLOSE,HIGH,LOW,OPEN,VOLUME 
DATA= 
TIMEZONE_OFFSET=120 
a1491405000,5098.75,5099.92,5098.75,5099.92,0 
1,5100.51,5100.51,5098.09,5098.09,0 
2,5099.63,5101.2,5099.29,5100.68,0 
3,5099.83,5100.04,5099.07,5099.28,0 
4,5098.19,5098.9,5097.71,5098.9,0 
5,5098.56,5099.24,5097.99,5099.24,0 
6,5097.34,5098.2,5096.14,5098.2,0 
7,5096.52,5097.38,5095.66,5097.38,0 
8,5093.27,5095.39,5093.27,5095.39,0 
9,5094.43,5094.43,5092.07,5093.17,0 
10,5088.18,5092.72,5087.68,5092.72,0 

的XHR應列表中的每個股票代碼來完成,那麼結果應該併入表。

+0

感謝這個。我擁有的問題是,雖然Google有一個API,但這只是一個例子,大多數網頁都沒有API,所以這不是我能爲他們做的事情。有沒有其他方法可以解決這個問題? – Jeremy

+0

@Jeremy可以請你提供另一個你需要刮取的網站URL,以及哪個不提供API,舉個例子?我會試着說出一些一般的指導方針。 – omegastripes

+0

我已經得到了我的頭,圍繞CSS querySelectorAll,並且循環遍歷Parentelements中的元素(我不知道這可以按照您對'範圍內每個'loop範圍的相同方式完成),所以問題得以解決 - 您嘗試提供幫助的最佳答案!謝謝 :) – Jeremy