Vb.net 通过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

背景

因此,我正在创建一个VB.NET程序,它基本上可以登录到一个网页,点击一系列按钮,这将导致网站生成一个可以下载的excel报告。我已经成功地完成了生成文件的所有步骤,因此现在我正在尝试创建一种方法,该方法将在后台下载文件,而不会出现“另存为”对话框

详细信息

我已通过Webbrowser控件的导航事件成功捕获下载:

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
    
我验证了在身份验证过程中捕获了两个cookie:

因此,我尝试在下载之前将Cookie重新应用到我的WebClient:

   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")
...