我在使用VBA進行POST httprequest時遇到問題。我有一些參數和JSON東西的提琴手日誌。參數是兩個,JSON(也是那個參數?)是一個。它看起來像:如何使用VBA進行復雜的POST
這裏是我的問題 - 如何將這些參數發送所有在一起嗎?理想情況下在VBA中,但即使是一般的答案也會很好。
我想說我有點兒新東西。
問候, 盧克。
我在使用VBA進行POST httprequest時遇到問題。我有一些參數和JSON東西的提琴手日誌。參數是兩個,JSON(也是那個參數?)是一個。它看起來像:如何使用VBA進行復雜的POST
這裏是我的問題 - 如何將這些參數發送所有在一起嗎?理想情況下在VBA中,但即使是一般的答案也會很好。
我想說我有點兒新東西。
問候, 盧克。
嘗試將請求中提供適當的餅乾和Content-Type頭,看看下面的例子,它採用MSXML2.ServerXMLHTTP
與cookies來管理:
Option Explicit
Sub scrape_kody_poczta_polska_pl()
Dim sRespHeaders As String
Dim aSetHeaders
Dim sPayload As String
Dim sRespText As String
Dim aRows
Dim aCells
Dim i As Long
Dim j As Long
Dim aData
' Get search page to retrieve cookies
XmlHttpRequest _
"GET", _
"http://kody.poczta-polska.pl/", _
Array(), _
"", _
sRespHeaders, _
""
' Extract cookies
ParseResponse "^Set-(Cookie): (\S*?=\S*?);[\s\S]*?$", sRespHeaders, aSetHeaders
' Setup request
sPayload = "kod=20-610&page=kod"
PushItem aSetHeaders, Array("Content-Type", "application/x-www-form-urlencoded")
' Retrieve results
XmlHttpRequest _
"POST", _
"http://kody.poczta-polska.pl/index.php", _
aSetHeaders, _
sPayload, _
"", _
sRespText
' Parse table rows
ParseResponse _
"(<tr>(?:[\s\S]*?<t[dh]>[\s\S]*?</t[dh]>)+?[\s\S]*?</tr>)", _
sRespText, _
aRows
' Parse table cells
For i = 0 To UBound(aRows)
ParseResponse _
"<t[dh]>([\s\S]*?)</t[dh]>", _
aRows(i), _
aCells, _
False
For j = 0 To UBound(aCells)
aCells(j) = DecodeHTMLEntities((aCells(j)))
Next
aRows(i) = aCells
Next
' Output
With ThisWorkbook.Sheets(1)
.Cells.Delete
.Cells.HorizontalAlignment = xlCenter
.Cells.VerticalAlignment = xlTop
aData = Denestify(aRows)
If IsArray(aData) Then Output2DArray .Cells(1, 1), aData
End With
End Sub
Sub XmlHttpRequest(sMethod, sUrl, aSetHeaders, sPayload, sRespHeaders, sRespText)
Dim aHeader
With CreateObject("MSXML2.ServerXMLHTTP")
.SetOption 2, 13056 ' SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS
.Open sMethod, sUrl, False
For Each aHeader In aSetHeaders
.SetRequestHeader aHeader(0), aHeader(1)
Next
.Send sPayload
sRespHeaders = .GetAllResponseHeaders
sRespText = .ResponseText
End With
End Sub
Sub ParseResponse(sPattern, sResponse, aData, Optional bAppend As Boolean = True)
Dim oMatch
Dim aTmp()
Dim sSubMatch
If Not (IsArray(aData) And bAppend) Then aData = Array()
With CreateObject("VBScript.RegExp")
.Global = True
.MultiLine = True
.Pattern = sPattern
For Each oMatch In .Execute(sResponse)
If oMatch.SubMatches.Count = 1 Then
PushItem aData, oMatch.SubMatches(0)
Else
aTmp = Array()
For Each sSubMatch In oMatch.SubMatches
PushItem aTmp, sSubMatch
Next
PushItem aData, aTmp
End If
Next
End With
End Sub
Sub PushItem(aData, vItem, Optional bAppend As Boolean = True)
If Not (IsArray(aData) And bAppend) Then aData = Array()
ReDim Preserve aData(UBound(aData) + 1)
aData(UBound(aData)) = vItem
End Sub
Function DecodeHTMLEntities(sText As String) As String
Static oHtmlfile As Object
Static oDiv As Object
If oHtmlfile Is Nothing Then
Set oHtmlfile = CreateObject("htmlfile")
oHtmlfile.Open
Set oDiv = oHtmlfile.createElement("div")
End If
oDiv.innerHTML = sText
DecodeHTMLEntities = oDiv.innerText
End Function
Function Denestify(aRows)
Dim aData()
Dim aItems()
Dim i As Long
Dim j As Long
If UBound(aRows) = -1 Then Exit Function
ReDim aData(1 To UBound(aRows) + 1, 1 To 1)
For j = 0 To UBound(aRows)
aItems = aRows(j)
For i = 0 To UBound(aItems)
If i + 1 > UBound(aData, 2) Then ReDim Preserve aData(1 To UBound(aRows) + 1, 1 To i + 1)
aData(j + 1, i + 1) = aItems(i)
Next
Next
Denestify = aData
End Function
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
對我來說,輸出如下:
,這是一樣的網頁結果:
我在下面添加一些變量值,它可能有助於在出現任何問題時進行調試。要觀看sRespHeaders
和sRespText
的內容,我使用了額外的procedure WriteTextFile
from this answer。提取Cookie後
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Date: Sat, 26 Aug 2017 14:24:48 GMT
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Server: Apache
Set-Cookie: PHPSESSID=rl4gc6nq91tfb34u2inj634u10; path=/
Set-Cookie: restrwww4=!hN5+tRTsssR9ii3Yf8b335uDNFxhmd5PNCjvCndeUeIwBxZnB38oHuGc9Nz19debb6vLbW1nYQ+Ncgw=; path=/; Httponly
X-Cnection: close
aSetHeaders
:
sRespHeaders
第一XmlHttpRequest
呼叫後(執行WriteTextFile sRespHeaders, "C:\tmp.txt", -1
)
有關部分sRespText
含有第二XmlHttpRequest
呼叫之後與目標數據的表(執行WriteTextFile sRespText, "C:\tmp.htm", -1
):
<table border="0" width="100%">
<tr>
<th>lp.</th>
<th>kod PNA</th>
<th>nazwa <br />(firmy lub placówki pocztowej)</th>
<th>miejscowość</th>
<th>adres</th>
<th>województwo</th>
<th>powiat</th>
<th>gmina</th>
</tr>
<tr>
<td>1.</td>
<td>20-610</td>
<td></td>
<td>Lublin</td>
<td> Kajetana Hryniewieckiego <br />
<i>numery od 1 do końca obie strony</i>
</td>
<td>LUBELSKIE</td>
<td>Lublin</td>
<td>Lublin</td>
</tr>
<tr>
<td>2.</td>
<td>20-610</td>
<td></td>
<td>Lublin</td>
<td> Leszka Czarnego <br />
<i>numery od 1 do końca obie strony</i>
</td>
<td>LUBELSKIE</td>
<td>Lublin</td>
<td>Lublin</td>
</tr>
<tr>
<td>3.</td>
<td>20-610</td>
<td></td>
<td>Lublin</td>
<td> Mieszka I <br />
<i>numery od 1 do końca obie strony</i>
</td>
<td>LUBELSKIE</td>
<td>Lublin</td>
<td>Lublin</td>
</tr>
<tr>
<td>4.</td>
<td>20-610</td>
<td></td>
<td>Lublin</td>
<td> Piastowska <br />
<i>numery od 1 do końca obie strony</i>
</td>
<td>LUBELSKIE</td>
<td>Lublin</td>
<td>Lublin</td>
</tr>
</table>
aRows
解析錶行後:
aRows
解析表格單元格後:
aData
後Denestify
電話:
非常感謝您的努力。你的代碼在你的機器上工作的確很棒,但是......我不知道爲什麼它不適用於我的機器。它只是刪除我excell表格中的所有輸入,但不填充任何數據。你有什麼想法,爲什麼? 我使用Office'03(公司規則)。 – Lucas
@Lucas我在Win 7 HB x64,Excel 2010 64位上運行代碼。沒有輸出意味着沒有在第二個響應中找到並解析表(包含問題中搜索頁面的相同響應)。嘗試逐步調試,並引用我發佈的變量值。 – omegastripes
你是否熟悉奇爾卡特? – Lucas
看到這個:https://stackoverflow.com/questions/44086334/curl-equivalent-to-post-json-data-using-vba – SlowLearner
不幸的是,它不涉及到我的問題,但由於很多努力。 – Lucas
不用擔心,如果你分享你已有的東西,通常你會得到更多的幫助,也許使用上面的代碼(來自內部鏈接的代碼)作爲編寫可能工作的基礎的基礎,並回來一些更具體的問題;-) – SlowLearner