簡體   English   中英

宏使用 serverxmlhttp 請求獲取部分響應

[英]Macro gets partial response using serverxmlhttp requests

我正在嘗試從網頁中提取street addressbuilder name 當我使用xmlhttp60請求時,我會相應地獲得這些字段。 但是,當我serverxmlhttp60請求 serverxmlhttp60 時,大多數時候我都會得到部分響應,因此腳本只打印street adddress 我使用json 轉換器從該站點的 json 內容中解析builder name

這是概念證明:

Sub GrabPropertyInfo()
    Const siteLink$ = "https://www.redfin.com/TX/Austin/604-Amesbury-Ln-78752/unit-2/home/171045975"

    Dim oPost As Object, oData As Object, Html As HTMLDocument
    Dim jsonObject As Object, jsonStr As Object, propertyMainRaw$
    Dim itemStr As Variant, sResp As String, oElem As Object
    Dim propertyContainer As Object, propertyMain As Object
    
    Set Html = New HTMLDocument
    
'    With CreateObject("MSXML2.XMLHTTP")
'        .Open "GET", siteLink, False
'        .setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"
'        .send
'        sResp = .responseText
'        Html.body.innerHTML = .responseText
'    End With
    
    With CreateObject("MSXML2.ServerXMLHTTP.6.0")
        .Open "GET", siteLink, True
        .setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"
        .send
        While .readyState < 4: DoEvents: Wend
        sResp = .responseText
        Html.body.innerHTML = .responseText
    End With

    Debug.Print "Street address: " & Html.querySelector("h1.homeAddress > .street-address").innerText
    
    With CreateObject("VBScript.RegExp")
        .Global = True
        .Pattern = "reactServerState\.InitialContext = (.*);"
        .MultiLine = True
        Set jsonStr = .Execute(sResp)
    End With
    

    itemStr = jsonStr(0).submatches(0)
    Set jsonObject = JsonConverter.ParseJson(itemStr)
    Set propertyMain = jsonObject("ReactServerAgent.cache")("dataCache")("/stingray/api/home/details/mainHouseInfoPanelInfo")("res")
    propertyMainRaw = Replace(propertyMain("text"), "{}&&", "")

    On Error Resume Next
    Set propertyContainer = JsonConverter.ParseJson(propertyMainRaw)("payload")("mainHouseInfo")("amenitiesInfo")("superGroups")
    On Error GoTo 0

    If Not propertyContainer Is Nothing Then
        For Each oElem In propertyContainer
            For Each oPost In oElem("amenityGroups")
                If InStr(oPost("groupTitle"), "Building Information") > 0 Then
                    For Each oData In oPost("amenityEntries")
                        If InStr(oData("amenityName"), "Builder Name") > 0 Then
                            Debug.Print "Builder Name: " & oData("amenityValues")(1)
                        End If
                    Next oData
                End If
            Next oPost
        Next oElem
    End If
End Sub

使用 xmlhttp 請求,我總是得到:

Street address: 604 Amesbury Ln #2,
Builder Name: Zach Savage

使用 serverxmlhttp 請求,大多數時候我得到以下結果:

Street address: 604 Amesbury Ln #2,

如何使用 serverxmlhttp 請求獲得完整響應?

編輯:

根據答案和評論,很明顯,如果我使用xmlhttp請求從該站點抓取browserid並在使用serverxmlhttp發送請求時將該browserid的值用作 cookie,我將獲得所需的結果。 但是,問題是我使用xmlhttp請求獲得的sz9u0xmCQKKV9Wu0jRa3Yg browserid而我可以在頁面源代碼中看到這個值v-J5D2IUSyqXizI7MG67fQ 我怎樣才能得到后者的價值? 這就是我解析browserid的方式。

Sub FetchBrowserId()
    Const siteLink$ = "https://www.redfin.com/TX/Austin/604-Amesbury-Ln-78752/unit-2/home/171045975"
 
    Dim Rxp As Object, browserId As Object, sRes$, cookie$
 
    Set Rxp = CreateObject("VBScript.RegExp")
 
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", siteLink, False
        .setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36"
        .send
        sRes = .responseText
    End With
 
    With Rxp
        .Global = True
        .Pattern = "window.__rfBrowserId=""(.*?)"";"
        .MultiLine = True
        Set browserId = .Execute(sRes)
    End With
 
    cookie = browserId(0).submatches(0)
    Debug.Print cookie
End Sub

所以我想真正的問題是為什么MSXML2.XMLHTTPMSXML2.ServerXMLHTTP對同一個 URL 的請求會返回不同的響應。

MSXML2.XMLHTTP使用 WinINet 堆棧, MSXML2.ServerXMLHTTP使用 WinHTTP 堆棧。 查看WinINet 與 WinHTTP文章了解更多詳細信息。

WinINet 提供對 cookies 的完整處理(順便說一句,IE 也依賴它)。 因此,您有不同響應的第一個原因是發送到服務器的 cookies 可能會影響流量。 它可以很容易地與任何服務進行比較,例如Webhook.site 當您使用MSXML2.XMLHTTP發出第二個請求時,Web 服務會記錄已從第一個響應中接受的 cookies。

還要考慮 SSL 條件。 How's My SSL 提出請求? 通過MSXML2.XMLHTTPMSXML2.ServerXMLHTTP ,並在瀏覽器(即 Chrome)中點擊鏈接並比較結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM