使用VBA刮掉AJAX页面
我一直在尝试刮掉整个整个 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和到了检查标签准确的文本(即低于黄色区域内的文本的全部。) - 如果我能得到这个(全扩展的)我可以从那里工作。任何帮助将大规模赞赏。
在上面的例子中(谷歌财经),该指数价格异步更新 - 我想在在我指定的字符串时捕捉到这些。
您刚才检查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
将它放到网址:
响应包含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_fix
,c_fix
,cp_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应列表中的每个股票代码来完成,那么结果应该并入表。
感谢这个。我拥有的问题是,虽然Google有一个API,但这只是一个例子,大多数网页都没有API,所以这不是我能为他们做的事情。有没有其他方法可以解决这个问题? – Jeremy
@Jeremy可以请你提供另一个你需要刮取的网站URL,以及哪个不提供API,举个例子?我会试着说出一些一般的指导方针。 – omegastripes
我已经得到了我的头,围绕CSS querySelectorAll,并且循环遍历Parentelements中的元素(我不知道这可以按照您对'范围内每个'loop范围的相同方式完成),所以问题得以解决 - 您尝试提供帮助的最佳答案!谢谢 :) – Jeremy
请问您可以添加到您的问题的预期产出?目前尚不清楚开发人员工具中提供的文字是什么。 – omegastripes
@omegastripes我已经包括了最后一句 - 如果我正在寻找CAC 40(法国证券交易所)价值,我目前无法提取它,因为它不包含在'Debug.print'中。 – Jeremy