Vb.net 通过WebBrowser验证后下载文件
背景 因此,我正在创建一个VB.NET程序,它基本上可以登录到一个网页,点击一系列按钮,这将导致网站生成一个可以下载的excel报告。我已经成功地完成了生成文件的所有步骤,因此现在我正在尝试创建一种方法,该方法将在后台下载文件,而不会出现“另存为”对话框 详细信息 我已通过Webbrowser控件的导航事件成功捕获下载:Vb.net 通过WebBrowser验证后下载文件,vb.net,download,webbrowser-control,webclient,Vb.net,Download,Webbrowser Control,Webclient,背景 因此,我正在创建一个VB.NET程序,它基本上可以登录到一个网页,点击一系列按钮,这将导致网站生成一个可以下载的excel报告。我已经成功地完成了生成文件的所有步骤,因此现在我正在尝试创建一种方法,该方法将在后台下载文件,而不会出现“另存为”对话框 详细信息 我已通过Webbrowser控件的导航事件成功捕获下载: Public Sub a(sender As Object, e As WebBrowserNavigatingEventArgs) Handles WebBrowser1.N
Public Sub a(sender As Object, e As WebBrowserNavigatingEventArgs) Handles WebBrowser1.Navigating
'intercept the excel download. Retrieve the url but cancel dialog
If e.Url.AbsoluteUri.Contains("fmsdownload") Then
Label3.Text = e.Url.AbsoluteUri
e.Cancel = True
'e.Url.AbsoluteUri = the temporarily generated file URL to download from
'INSERT DOWNLOAD METHOD HERE
End If
End Sub
我验证了e.Url.AbsoluteUri
确实是正确的路径。如果我将此URL复制/粘贴到Chrome中,它将下载
问题
因此,最终我只是想找到一种在下载链接生成后下载文件的方法。请看下面的部分,了解我所做的尝试,因为我相信我即将取得成功
我尝试过的内容(请在发布前阅读)
- 方法1:
。这导致服务器回退My.Computer.Network.DownloadFile(URL,SAVEPATH)
repote服务器返回错误:(403)禁止
。这让我明白身份验证没有通过,这是有道理的
- 方法2:我读了一篇stackoverflow文章,尝试使用URLMON启动下载()。我原以为这会带来一些希望,但结果是错误
无法在DLL“URLMON.DLL”中找到名为URLDownloadToFile的入口点
以下是我用于此方法的代码,因为我可能缺少一些简单的代码:
端接头Private Declare Sub URLDownloadToFile _ Lib "URLMON.dll" ( ByVal lpCaller As Long, ByVal szUrl As String, ByVal szFilename As String, ByVal dwReserved As Long, ByVal lpBindStatusCallback As Long) Public Sub a(sender As Object, e As WebBrowserNavigatingEventArgs) Handles WebBrowser1.Navigating 'intercept the excel download. Retrieve the url but cancel dialog If e.Url.AbsoluteUri.Contains("fmsdownload") Then Label3.Text = e.Url.AbsoluteUri e.Cancel = True Try Kill(My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\download.xls") Catch End Try URLDownloadToFile(0, e.Url.AbsoluteUri, My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\download.xls", 0, 0) End If
- 方法3:经过一些研究,似乎身份验证存储为cookies,因此我尝试检索cookies,然后将它们提供回WebClient,因为WebClient支持下载文件。下面是我捕获cookies的地方:
Dim cookie_collection() As String Public Sub webbrowser1_documentcompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted If WebBrowser1.Document.Cookie Is Nothing Then Else Dim cookies As String() = WebBrowser1.Document.Cookie.Split({";"c}, StringSplitOptions.None) For Each cookie As String In cookies Dim name As String = cookie.Substring(0, cookie.IndexOf("="c)).TrimStart(" "c) Dim value As String = cookie.Substring(cookie.IndexOf("="c) + 1) If cookie_collection Is Nothing Then ReDim cookie_collection(0) Else ReDim Preserve cookie_collection(cookie_collection.Length) End If cookie_collection(cookie_collection.Length - 1) = cookie ' MsgBox(cookie) Next cookie End If End Sub
Public Sub a(sender As Object, e As WebBrowserNavigatingEventArgs) Handles WebBrowser1.Navigating
'intercept the excel download. Retrieve the url but cancel dialog
If e.Url.AbsoluteUri.Contains("fmsdownload") Then
Label3.Text = e.Url.AbsoluteUri
e.Cancel = True
Dim client As New System.Net.WebClient
For Each cookie As String In cookie_collection
client.Headers.Add(Net.HttpRequestHeader.Cookie, cookie)
Next
client.DownloadFile(e.Url.AbsoluteUri, My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\download.xls")
End If
End Sub
不幸的是,这导致了与之前相同的错误repote服务器返回了一个错误:(403)禁止,这使我意识到身份验证仍然没有通过
我知道这是一篇大文章,但我觉得方法2或方法3应该可以工作,所以我可能遗漏了一些小东西(我希望)。在您的最后一段代码中,您使用WebClient
检索文件,您当前将cookie添加到请求中,如下所示:
For Each cookie As String In cookie_collection
client.Headers.Add(Net.HttpRequestHeader.Cookie, cookie)
Next
但是,HTTP中只有一个参数一次包含所有cookie,因此您通过为每个cookie推送一个新的头来覆盖以前的cookie。因此,您不需要使用String.Split来提取cookie,而是按原样用分号传递参数,因为HTTP应该解决所有问题。希望这能解决你的问题
编辑:以下是我认为可以解决的问题:
在DocumentCompleted
事件中检索cookie,如下所示(第三位代码):
然后,只需将cookie\u集合
字段传递到标题即可:
...
Dim client As New System.Net.WebClient
client.Headers.Add(Net.HttpRequestHeader.Cookie, cookie_collection)
client.DownloadFile(e.Url.AbsoluteUri, My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\download.xls")
...
谢谢你的回复!我试图替换我的初始代码,但仍然得到禁止的错误。是否缺少其他内容?:如果WebBrowser1.Document.Cookie为Nothing,则将Cookie变暗为String=WebBrowser1.Document.Cookie如果Cookie\u集合为Nothing,则重拨Cookie\u集合(0)否则重拨保留Cookie\u集合(cookie\u collection.Length)如果cookie\u collection(cookie\u collection.Length-1)结束=cookie End If
我实际上指的是最后一位代码而不是第三位,很抱歉!只是编辑了它。没问题,但不幸没有骰子。我仍然得到禁止的错误。下面是我的结果标题:cookie:csrf_cookie=ade98ec8-1558-4517-b5ea-3d1a4507bf5f;JSESSIONID=iyay4wex2kCqxR-wbjn19lf1fBvBvxVumpDv7v-kZuOSKFxoCi!147640388!-765605226;csrf_cookie=10150dc2-5b65-4b62-a27a-d934baedb187;JSSessionId=iyay4Wex2KcqxCr-WBJN19LF1FbxVuMpbPdV7V-kZuOSKFxoCi!147640388!-765605226
您认为csrf_cookie
和JSSessionID
设置两次是一个问题吗?仅供参考,我尝试过操作,所以只加载了第一组cookie还有第二组cookie,仍然是一个禁止的错误……这很不幸……但是通过WebBrowser
下载文件工作正常,我想?您是否尝试过通过WebBrowser
手动下载过程捕获cookie集,并查看它们是否不同?另外,唯一的参数似乎是constant是JSESSIONID
,因此可能尝试只传递此参数作为唯一的cookie。如果仍然没有任何效果,则问题可能与cookie无关,而是与其他身份验证失败有关,例如HTTP身份验证(尽管我认为这不太可能)
...
Dim client As New System.Net.WebClient
client.Headers.Add(Net.HttpRequestHeader.Cookie, cookie_collection)
client.DownloadFile(e.Url.AbsoluteUri, My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\download.xls")
...