Вы можете быть в состоянии поразить цель формы непосредственно с POST (действием = «/ PDQ/SurveyOutputServlet»), но он ожидает после строки из < ввода > элементов вместе с их значениями. Большинство, если не все эти элементы ввода были заполнены для вас, просто перейдя на эту страницу. Все, что вам нужно сделать, это собрать и объединить их в строку сообщения, которую нужно отбросить в форму.
Option Explicit
'base web page
Public Const csBLSGOVpg = "http://data.bls.gov/timeseries/LNS14000000"
'form's action target
Public Const csXLSDLpg = "http://data.bls.gov/pdq/SurveyOutputServlet"
Sub mcr_Stream_Buyer_Documents()
Dim xmlDL As New MSXML2.ServerXMLHTTP60, xmlBDY As New HTMLDocument, adoFILE As Object
Dim xmlSend As String, strFN As String, f As Long, i As Long
With xmlDL
.SetTimeouts 5000, 5000, 15000, 25000
'start by going to the base web page
.Open "GET", csBLSGOVpg, False
.setRequestHeader "Content-Type", "text/javascript"
.send
If .Status <> "200" Then GoTo bm_Exit
'get the source HTML for examination; zero the post string var
xmlBDY.body.innerHTML = .responseText
xmlSend = vbNullString
'loop through the forms until you find the right one
'then loop through the input elements and construct a post string
For f = 0 To xmlBDY.getElementsByTagName("form").Length - 1
If xmlBDY.getElementsByTagName("form")(f).Name = "excel" Then
With xmlBDY.getElementsByTagName("form")(f)
For i = 0 To .getElementsByTagName("input").Length - 1
xmlSend = xmlSend & Chr(38) & _
.getElementsByTagName("input")(i).Name & Chr(61) & _
.getElementsByTagName("input")(i).Value
Next i
xmlSend = "?.x=5&.y=5" & xmlSend
End With
Exit For
End If
Next f
'Debug.Print xmlSend 'check the POST string
'send the POST string back to the form's action target
.Open "POST", csXLSDLpg, False
xmlDL.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlDL.send xmlSend
If xmlDL.Status <> "200" Then GoTo bm_Exit
'pick up the response as a stream and save it as a .XLSX
strFN = Environ("USERPROFILE") & "\Documents\LNS14000000" & Format(Date, "yyyymmdd") & ".xlsx"
On Error Resume Next
Kill strFN
On Error GoTo 0
Set adoFILE = CreateObject("ADODB.Stream")
adoFILE.Type = 1
adoFILE.Open
adoFILE.Write .responseBody
adoFILE.SaveToFile strFN, 2
Set adoFILE = Nothing
End With
Set xmlBDY = Nothing
Set xmlDL = Nothing
Exit Sub
bm_Exit:
Debug.Print Err.Number & ":" & Err.Description
End Sub
Это довольно минималистский, но это все, что вам нужно. Существует хотя бы один нестандартный элемент ввода, который не имеет имени, но я решил отправить его значение в любом случае. Я не последовательно удалял вещи, пока не сломался; Я только что построил строку POST с учетом того, что я получил и отправил обратно.
LNS1400000020150916.xlsx
Вы, вероятно, будет двигаться этот код в какой-то цикл. Соответственно отрегулируйте имя получателя. Каждая новая страница должна соответствующим образом настраивать собственные элементы ввода формы.
IMO вы должны использовать запрос POST, а не GET в вашем случае. Откройте страницу, например, в инструментах разработчика Chrome (нажмите F12), на вкладке Elements найдите форму 'excel', delete' target = "_ blank" и щелкните значок файла после загрузки файла, перейдите на вкладку Сеть и вы см. запрос POST запроса SurveyOutputServlet. Рассмотрим [пример получения данных csv через XHR] (http://stackoverflow.com/a/32429348/2165759). – omegastripes
@omegastripes Я попробовал это, указав URL как «http://data.bls.gov/pdq/SurveyOutputServlet» и используя POST, как вам было предложено, но затем я получаю сообщение об ошибке, что расширение файла недействительно, а также я получаю содержимое веб-страницы на листе excel вместо данных. Пожалуйста, оставьте комментарий, если сможете. Спасибо за вашу помощь. – Meesha
Взгляните на [мой скриншот] (http://i.stack.imgur.com/wNhgb.png), есть куча параметров данных формы, типичных для POST XHR. Я связал некоторые из них с параметрами страницы, чтобы показать их общую цель. Поэтому вам нужно отправить все параметры с запросом. Нажмите источник просмотра ('output_type = default & years_option = specific_years & from_year = 2005 & ...'), и вы поймете, как создать строку для отправки. См. Мой пример по ссылке выше. – omegastripes