1

我正在尝试自动在服务器上下载动态生成的文件,所以这里是我必须手动执行的步骤 -

  1. 使用我的凭据登录该站点 - 它使用 NTLM 进行身份验证。
  2. 登录后在表单中填写详细信息,该表单使用 post 方法将详细信息发送到服务器并在服务器上生成一个文件并将响应返回给服务器。

所以首先我想用VBScript来做:

  • 获取 IE 自动化对象

  • sendkeys 发送用户密码/密码

  • 导航到页面并下载文件

  • 发送键切换到保存按钮 - 但在这里我卡住了,因为 IE 提示我输入我无法确定的保存位置。我也想过打开它,但我无法以这种方式打开 Excel 文件的自动化对象:(

甚至wget无法工作,因为我必须发布一些数据和基础,它将为我提供生成的 Excel 文件。

因此,在网上搜索后,我发现我可以使用MSXML2.xmlhttp对象或 Java 套接字并使用 get 方法下载页面,但我必须再次提供我的凭据才能打开页面。

那么任何人都可以帮助我如何验证用户并以任何一种方式下载文件。

编辑:代码

--下载页面

objmsXML.Open "GET", url, False
objmsXML.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
objmsXML.setRequestHeader "Referer", url
objmsXML.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"
objmsXML.send

--填写详细信息并发布数据

If objmsXML.Status = 200 Then
  'First Response received.
  'get all the response headers
  responseHeaders = objmsXML.getAllResponseHeaders()
  responseBody = objmsXML.responseText    
End If

Dim viewState As String
Dim eventTarget, eventArgument, txtProjectID, btnSubmit, grdReportPostDataValue
Dim eventValidation As String

viewState = Split(Split(responseBody, "__VIEWSTATE")(2), """")(2)
viewState = URLEncode(viewState, False)

eventTarget = ""
eventArgument = ""
txtProjectID = projectID
btnSubmit = URLEncode("Submit")
grdReportPostDataValue = ""
eventValidation = Split(Split(responseBody, "__EVENTVALIDATION")(2), """")(2)
eventValidation = URLEncode(eventValidation, False)

objmsXML.Open "POST", url, False

Dim postData
postData = "__EVENTTARGET=" & eventTarget & "&__EVENTARGUMENT=" _
  & eventArgument & "&__VIEWSTATE=" & viewState & "&txtProjectID=" _
  & txtProjectID & "&btnSubmit=" & btnSubmit & "&grdReportPostDataValue" _
  & grdReportPostDataValue & "&__EVENTVALIDATION=" & eventValidation

objmsXML.send postData

但问题是它没有因为表单发布而给我第二页。我相信这可能是因为我无法跟踪会话 cookie。请帮忙。

4

1 回答 1

0

您无法在不提供凭据的情况下对用户进行身份验证。在使用Fiddler之类的工具检查会话时手动下载文件一次。POST这将显示请求所需的标头。然后像这样自动化请求:

url = "http://..."

user = "..."
pass = "..."
credentials = "username=" & user & "&password=" & pass

Set req = CreateObject("Msxml2.XMLHttp.6.0")
req.open "POST", url, False
req.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
req.send credentials

credentials根据 Fiddler 透露的内容进行修改。您可能需要使用以下内容对值(user以及pass在上面的示例中)进行编码:

Function Encode(ByVal str)
  Set re = New RegExp
  re.Pattern = "[^a-zA-Z0-9_.~-]"

  enc = ""
  For i = 1 To Len(str)
    c = Mid(str, i, 1)
    If re.Test(c) Then c = "%" & Right("0" & Hex(Asc(c)), 2)
    enc = enc & c
  Next

  Encode = enc
End Function

保存responseBody到这样的文件:

filename = "C:\your\output.xls"

Set stream = CreateObject("ADODB.Stream")

If req.status = 200 Then
  stream.Open
  stream.Type = 1 'binary
  stream.Write req.responseBody
  stream.SaveToFile filename, 2
  stream.Close
End If

如果文件名是动态生成的,您可能需要读取响应和/或状态文本并发送第二个请求以实际检索文件。但是,这取决于实际的服务器响应(正如 Fiddler 所揭示的那样)。

编辑:我在这里找到的解决方案建议使用一个WinHttpRequest对象:

Set req = CreateObject("WinHttp.WinHttpRequest.5.1")
req.SetAutoLogonPolicy 0

req.Open "POST", url, False
req.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
req.Send credentials

不过,我无法对此进行测试,因为我手头没有使用 NTLM 身份验证的 Web 服务器。

于 2013-06-14T08:35:40.637 回答