【问题标题】:Scrape Realtime data using VBA使用 VBA 抓取实时数据
【发布时间】:2021-11-08 10:59:27
【问题描述】:

我想使用 VBA 从https://iboard.ssi.com.vn/bang-gia/hose 抓取实时数据。

我的代码如下;但它不会返回其中包含数据的 html 文件。我寻找但也找不到指向 JSON 数据的链接。

Sub Get_ssi_data()
       
    Dim xmlhttp As Object
    Set xmlhttp = CreateObject("MSXML2.XMLHTTP")
    
    xmlhttp.Open "GET", "https://iboard.ssi.com.vn/bang-gia/hose"
    xmlhttp.send
    
    Debug.Print xmlhttp.responseText
      
End Sub

您能否建议如何获取实时数据?

【问题讨论】:

    标签: javascript html json vba web-scraping


    【解决方案1】:

    不清楚您要查找数据的哪一部分,但我假设您需要主表。

    多个API被调用到端点https://gateway-iboard.ssi.com.vn/graphql,以不同的请求体来获取具体信息。

    在 DevTools 中,主表的请求正文如下:

    {"operationName":"stockRealtimes","variables":{"exchange":"hose"},"query":"query stockRealtimes($exchange: String) {\n  stockRealtimes(exchange: $exchange) {\n    stockNo\n    ceiling\n    floor\n    refPrice\n    stockSymbol\n    stockType\n    exchange\n    matchedPrice\n    matchedVolume\n    priceChange\n    priceChangePercent\n    highest\n    avgPrice\n    lowest\n    nmTotalTradedQty\n    best1Bid\n    best1BidVol\n    best2Bid\n    best2BidVol\n    best3Bid\n    best3BidVol\n    best4Bid\n    best4BidVol\n    best5Bid\n    best5BidVol\n    best6Bid\n    best6BidVol\n    best7Bid\n    best7BidVol\n    best8Bid\n    best8BidVol\n    best9Bid\n    best9BidVol\n    best10Bid\n    best10BidVol\n    best1Offer\n    best1OfferVol\n    best2Offer\n    best2OfferVol\n    best3Offer\n    best3OfferVol\n    best4Offer\n    best4OfferVol\n    best5Offer\n    best5OfferVol\n    best6Offer\n    best6OfferVol\n    best7Offer\n    best7OfferVol\n    best8Offer\n    best8OfferVol\n    best9Offer\n    best9OfferVol\n    best10Offer\n    best10OfferVol\n    buyForeignQtty\n    buyForeignValue\n    sellForeignQtty\n    sellForeignValue\n    caStatus\n    tradingStatus\n    currentBidQty\n    currentOfferQty\n    remainForeignQtty\n    session\n    __typename\n  }\n}\n"}
    

    因此,您需要将上述请求正文发送到端点,该端点将为您提供一个 JSON 响应,其中包含主表的原始数据,然后您需要自行处理它们以获得您想要的。

    Private Sub Get_ssi_data()
               
        Dim xmlhttp As Object
        Set xmlhttp = CreateObject("MSXML2.XMLHTTP")
        
        Dim reqBody As String
        reqBody = "{""operationName"":""stockRealtimes"",""variables"":{""exchange"":""hose""},""query"":""query stockRealtimes($exchange: String) {\n  stockRealtimes(exchange: $exchange) {\n    stockNo\n    ceiling\n    floor\n    refPrice\n    stockSymbol\n    stockType\n    exchange\n    matchedPrice\n    matchedVolume\n    priceChange\n    priceChangePercent\n    highest\n    avgPrice\n    lowest\n    nmTotalTradedQty\n    best1Bid\n    best1BidVol\n    best2Bid\n    best2BidVol\n    best3Bid\n    " & _
                    "best3BidVol\n    best4Bid\n    best4BidVol\n    best5Bid\n    best5BidVol\n    best6Bid\n    best6BidVol\n    best7Bid\n    best7BidVol\n    best8Bid\n    best8BidVol\n    best9Bid\n    best9BidVol\n    best10Bid\n    best10BidVol\n    best1Offer\n    best1OfferVol\n    best2Offer\n    best2OfferVol\n    best3Offer\n    best3OfferVol\n    best4Offer\n    best4OfferVol\n    best5Offer\n    best5OfferVol\n    best6Offer\n    best6OfferVol\n    best7Offer\n    best7OfferVol\n    best8Offer\n    best8OfferVol\n    best9Offer\n    best9OfferVol\n   best10Offer\n    best10OfferVol\n    buyForeignQtty\n    buyForeignValue\n    sellForeignQtty\n    sellForeignValue\n    caStatus\n    tradingStatus\n    currentBidQty\n    currentOfferQty\n    remainForeignQtty\n    session\n    __typename\n  }\n}\n""}"
        
        xmlhttp.Open "POST", "https://gateway-iboard.ssi.com.vn/graphql", False
        xmlhttp.setRequestHeader "Content-Type", "application/json"
        xmlhttp.send reqBody
        'xmlhttp.send (reqBody) 'For Excel 2013 (Credit to SIM in comment)
    
        Debug.Print xmlhttp.responseText
    
    End Sub
    

    编辑 - 在找到请求正文时

    在 Chrome Devtools 的网络选项卡下,您会看到该网站向graphql 发出了多个请求(按 Fetch/XHR 过滤以在列表中获得更小的结果)

    因为它们都调用同一个端点,这使得很难识别正确的表,所以我单击每个请求并查看其响应选项卡(即 JSON 字符串)。

    下面你可以看到我找到了返回主表数据的请求(JSON字符串通常是1长行,你可以点击Pretty Print(红色圈出)更容易阅读)

    找到所需的请求后,返回 Headers 选项卡并查看选项卡的末尾,您将找到 Request Payload 部分,即请求身体。您可以点击view source 获取纯文本版本,用于复制粘贴。

    【讨论】:

    • 如果你使用xmlhttp.send reqBody而不是xmlhttp.send (reqBody),某些版本的excel可能会报错。
    • 感谢您指出这一点,我不知道这个潜在的问题。你知道需要(reqBody)的具体Excel版本吗? @SIM
    • 是的,例如 excel 2013。
    • @SIM Cool,我已经编辑了我的答案并将其包含在内以防万一!
    • 哦,太棒了@Raymond Wu 和 Sim,如此快速高效。我可能需要一些时间才能完全理解您分享的代码,但是通过这些代码行,我现在已经克服了被卡住的感觉,我可以继续自己处理 JSON 数据。非常感谢你们的帮助。
    猜你喜欢
    • 2020-10-14
    • 2015-01-19
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    相关资源
    最近更新 更多