java - 使用 vbscript/java 在 NTLM 身份验证后自动下载动态生成的文件

标签 java excel vbscript ntlm browser-automation

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

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

所以我首先想到使用 VBScript 来实现:

  • 获取 IE 自动化对象

  • sendkeys 发送用户名/密码

  • 导航至页面并下载文件

  • 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

但问题是,作为表单发布的结果,它没有给我第二页。我相信这可能是因为我无法跟踪 session cookie。请帮忙。

最佳答案

如果不提供凭据,您将无法对用户进行身份验证。在使用类似 Fiddler 检查 session 时手动下载文件一次。这将显示 POST 请求所需的 header 。然后像这样自动化请求:

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

根据 Fiddler 显示的内容修改凭据。您可能需要使用如下内容对值(上例中的 userpass)进行编码:

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 所示)。

编辑:我找到的解决方案 here建议使用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 服务器。

关于java - 使用 vbscript/java 在 NTLM 身份验证后自动下载动态生成的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17101130/

相关文章:

java - 谷歌浏览器 Java 解决方法

perl - 使用 Excel::Writer::XLSX 导出大型数据集时遇到问题

c# - 在 C# 中使用 OleDB 读取 excel 文件?

vbscript - UFT 图像用作按钮

asp-classic - 如何使用服务器端 vbscript 获取图像宽度?经典的ASP

windows - vbscript 按字母顺序插入一行

java - 我们可以在 JDK 8 中根据特定时间轮换 GC 日志吗?

java - Java 的形状识别算法/代码

java - 为什么 main 方法不能是默认范围?

Excel:Vlookup在命名范围内并返回范围之外的值