[英]Macro gets partial response using serverxmlhttp requests
我正在嘗試從網頁中提取street address
和builder 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.XMLHTTP
和MSXML2.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.XMLHTTP
和MSXML2.ServerXMLHTTP
,並在瀏覽器(即 Chrome)中點擊鏈接並比較結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.