【问题标题】:GET request data doesn't updateGET 请求数据不更新
【发布时间】:2019-03-16 19:46:20
【问题描述】:

我正在尝试从 API 检索数据,但即使我在 GET 请求之前将其设置为空,我的变量也不会更新。

只有当我关闭 Excel 并重新打开它时,变量的数据才会更新。

有什么解释吗?我已经挠头这么久了。

这里是代码

Sub getJsonResult()
    Dim objRequestt As Object
    Dim strUrl As String
    Dim blnAsync As Boolean
    Dim strUrlXBTUSD As String
    Dim strResponse As String
    Dim jsonText As String
    Dim jsonObject As Object, item As Object
    Dim i As Integer

    'setting up the variable to 0 or nothing

    strUrlXBTUSD = ""
    strResponsee = ""
    jsonText = ""
    i = 0
 blnAsync = False
 Set item = Nothing
 Set jsonObject = Nothing
 Set objRequestt = Nothing
 Set objRequestt = CreateObject("MSXML2.XMLHTTP")
    strUrlXBTUSD = "https://www.bitmex.com/api/v1/orderBook/L2?symbol=XBTUSD&depth=3"
    blnAsync = True


    'Starting the GET request

    ThisWorkbook.Activate
    With objRequestt
        .Open "GET", strUrlXBTUSD, blnAsync
        .SetRequestHeader "Content-Type", "application/json"
        .send
        strResponse = .responseText 'here the response is always the same except if i Close Excel
           Debug.Print strResponsee
    End With
End Sub

即使经过几次 F5 刷新,最后“strResponse”也始终相同。我可以看到数据在网络浏览器上不再准确。我希望 VBA 程序在不关闭 Excel 的情况下获取准确的数据并刷新。

怎么做?

【问题讨论】:

  • GET 请求是否被缓存了,是偶然的吗?
  • 另外,可能应该强制同步模式..?没有附加回调处理程序,所以我很惊讶甚至第一次“成功”获取。
  • 你称之为异步。 varAsync [可选] 布​​尔值。调用是否异步的指示符。默认值为 True(调用立即返回)。如果设置为 True,则附加一个 onreadystatechange 属性回调,以便您知道发送调用何时完成。。您的大多数代码行都是完全不必要的,并且会减慢您的代码速度。变量默认为nothing/false/0/""
  • 你好@user2864740,我不确定它是否被缓存。如何检查?如果可以,我该怎么办?
  • 你好@Noodles!你能解释一下如何附加一个onreadystatechange吗?我从来没有用过这样的东西!

标签: excel vba api web-scraping


【解决方案1】:

您可以添加一条指令以避免提供缓存结果(服务器可以忽略这一点,但我过去在这方面取得了很好的成功)。确保您的 async 参数始终为 False 并在测试之间留出更多时间。我注意到有时价格变化缓慢,因此您可能会由于间隔太小/尝试次数不足而错过变化。你会注意到size 的变化。您应该在底部脚本的循环中添加max timeout

还删除了匈牙利符号。

Option Explicit

Public Sub getJsonResult()
    Dim http As Object
    Dim urlXBTUSD As String
    Dim response As String
    Dim j As Long
    Const ASYNC_ARG As Boolean = False

    Set http  = CreateObject("MSXML2.XMLHTTP")
    For j = 1 To 10
        response = vbNullString
        urlXBTUSD = "https://www.bitmex.com/api/v1/orderBook/L2?symbol=XBTUSD&depth=3"

        With http 
            .Open "GET", urlXBTUSD,  ASYNC_ARG
            .setRequestHeader "Content-Type", "application/json"
            .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
            .send
            response = .responseText
            Debug.Print response
        End With
        Application.Wait Now + TimeSerial(0, 0, 15)
    Next
End Sub

这是一个漫长而乏味的证明方法,通过循环直到退货集合中第一个项目的价格发生变化。我使用 jsonconverter.bas 添加到项目和 VBE > 工具 > 参考 > Microsoft 脚本运行时参考。

Option Explicit

Public Sub getJsonResult()
    Dim http  As Object
    Dim urlXBTUSD As String
    Dim response As String
    Dim j As Long
    Const ASYNC_ARG As Boolean = False
    Dim price As String, firstValue As String

    Set http  = CreateObject("MSXML2.XMLHTTP")
    urlXBTUSD = "https://www.bitmex.com/api/v1/orderBook/L2?symbol=XBTUSD&depth=3"

    With http 
        .Open "GET", urlXBTUSD,  ASYNC_ARG
        .setRequestHeader "Content-Type", "application/json"
        .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
        .send
         firstValue = JsonConverter.ParseJson(.responseText)(1)("price")
        Debug.Print  firstValue
        Do
            .Open "GET", urlXBTUSD, blnAsync
            .setRequestHeader "Content-Type", "application/json"
            .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
            .send
            price = JsonConverter.ParseJson(.responseText)(1)("price")
            Application.Wait Now + TimeSerial(0, 0, 5)
        Loop While price = firstValue
        Debug.Print price
    End With
End Sub

【讨论】:

  • ."setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"" 确实改变了结果!如果您删除它,即使将异步布尔值设置为 FALSE 或 TRUE,我的问题也会再次出现。我知道我总是必须将异步布尔值设置为 FALSE,但这不是问题。谢谢,现在它正在工作。
【解决方案2】:

这是出于诊断目的。

On Error Resume Next
Set File = WScript.CreateObject("Msxml2.XMLHTTP.6.0")
File.Open "GET", "https://www.google.com.au/search?q=cat", False
File.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 1.1.4322; .NET CLR 3.5.30729; .NET CLR 3.0.30618; .NET4.0C; .NET4.0E; BCD2000; BCD2000)"
File.Send

wscript.echo "==================" 
    wscript.echo "" 
    wscript.echo "Error " & err.number & "(0x" & hex(err.number) & ") " & err.description 
    wscript.echo "Source " & err.source 
    wscript.echo "" 
    wscript.echo "Server Response " & File.Status & " " & File.StatusText
    wscript.echo    File.getAllResponseHeaders
    wscript.echo    File.ResponseBody

【讨论】:

  • 非常感谢 Noodles 的贡献。我的问题现在解决了,我必须添加一个 .setRequestHeader 规范,如上一篇文章中所述。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 2017-11-29
  • 1970-01-01
  • 2020-03-03
相关资源
最近更新 更多