在工作中,我们登录到提供商的网站,该网站充当文件存储库。出现文件列表。每个文件名都是一个链接。单击链接,然后下载文件。这是一个非常轻巧的网站。
我试图登录并下载文件,而没有单击每个文件的繁琐任务(没有“全选”复选框)。我正在使用带有“开始”按钮的表单上的WebBrowser控件。这是代码。请跳到星号行。
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
Try
PageLoaded = False
browser.Navigate("https://[the website]/Account/Login.htm", False)
While Not PageLoaded
Application.DoEvents()
End While
Catch ex As Exception
MsgBox(ex.Message)
End Try
Try
browser.Document.GetElementById("username").InnerText = [username]
browser.Document.GetElementById("password").InnerText = [password]
PageLoaded = False
browser.Document.Forms("mainform").InvokeMember("submit")
While Not PageLoaded
Application.DoEvents()
End While
Catch ex As Exception
MsgBox(ex.Message)
End Try
' ************************************
Dim mycookies As String
mycookies = browser.Document.Cookie
' DEBUG: verified cookies are indeed present
Try
Dim cookieJar As New CookieContainer
Dim cookies As String() = browser.Document.Cookie.Split({"; "}, StringSplitOptions.RemoveEmptyEntries)
Dim cookievaluepairs() = cookies(0).Split("=")
Dim cky As New Cookie(cookievaluepairs(0), cookievaluepairs(1))
cky.Domain = browser.Document.Domain
cookieJar.Add(cky)
Dim cookievaluepairs1() = cookies(1).Split("=")
Dim cky1 As New Cookie(cookievaluepairs(0), cookievaluepairs(1))
cky1.Domain = browser.Document.Domain
cookieJar.Add(cky1)
' DEBUG: verified cookieJar contains expected cookies
Dim wwwclient As New CookieAwareWebClient(cookieJar)
' DEBUG: please see class code below
Dim x As Integer
Dim dlurl As String = ""
Dim inputs As HtmlElementCollection = browser.Document.Links
For Each elm As HtmlElement In inputs
If Microsoft.VisualBasic.Left(elm.OuterHtml, 10) = "<A href=""/" Then
dlurl = elm.GetAttribute("href")
' DEBUG: crappily named dlurl indeed has correct URI
wwwclient.DownloadFile(dlurl, "D:\Desktop\file" & x)
' DEBUG: overriden function GetWebRequest fires
' please see class code below
End If
Next
Catch ex As Exception
MsgBox(ex.Message)
' DEBUG: always lands here with 401 error
End Try
End Sub
这里是在SO上找到的CookieAwareWebClient的众多版本之一。
Public Class CookieAwareWebClient
Inherits WebClient
Private m_container As CookieContainer = New CookieContainer()
Public Sub New(cc As CookieContainer)
m_container = cc
' DEBUG: verified m_container now has cookieJar passed as cc
End Sub
Protected Overrides Function GetWebRequest(ByVal address As Uri) As WebRequest
Dim request As WebRequest = MyBase.GetWebRequest(address)
Dim webRequest As HttpWebRequest = TryCast(request, HttpWebRequest)
If webRequest IsNot Nothing Then
webRequest.CookieContainer = m_container
End If
Return webRequest
' DEBUG: verified webRequest.CookieContainer is correct
End Function
End Class
我单步执行代码直到wwwclient.DownloadFile
语句,然后遍历GetWebRequest函数中的代码,暂停后,我得到了401 Not Authorized。我发现的五到六个CookieAwareWebClient版本都发生了这种情况。
代码成功登录后,我从WebBrowser控件中检索到的两个cookie如下所示(每次obv都有不同的令牌)。
"samlssologgedout=SSO%20Logged%20Out"
"token=A4AA416E-46C8-11e9-92CD-005056A005E4"
我已经验证了那些与“ webRequest.CookieContainer”中使用的cookie是相同的。同样,在WebBrowser控件中,登录后,您可以单击文件的链接进行下载。
有人在代码中看到明显的错误吗?
在写问题时仍在谷歌搜索,我只是在WebClient的MS文档中遇到Notes to Inheritors -“派生类应调用WebClient的基类实现以确保派生类按预期工作。” >
这听起来像您将在构造函数中执行的操作?还是在语句MyBase.GetWebRequest(address)
中解决了这个问题?
答案 0 :(得分:0)
在遭受了许多黑客和Google攻击之后,我将得出一个结论,那就是可以使WebClient“ Cookie感知”是一个神话。我永远无法使它工作,而我所读到的几乎所有线程都得出结论,没有解决方案。无论如何,显然不推荐使用WebClient。
总而言之,任务是自动从使用表单身份验证的低安全性网站登录和下载文件。 WebBrowser控件可以正常工作,只不过它使用IE,并且IE拒绝静默下载PDF文件。它坚持提示是否打开,保存或丢弃。
我开始使用HTTPWebRequest,HTTPRequest,WebRequest,HTTPClient和许多变体,但是一无所获。然后我想到了一个基于Chrome的WebBrowser控件,我偶然发现了Selenium。事实证明这是我的解决方案。
Selenium的主要用途似乎是测试软件,但它也可以让您操纵网页。您可以通过NuGet轻松在Visual Studio中安装它。您还需要安装特定于浏览器的驱动程序。每个主要浏览器都有驱动程序,但是使用IE驱动程序将毫无意义,因为我仍然会遇到在每个文件中都被提示的问题。相反,我下载了Chrome和Firefox驱动程序。他们允许用户在这两者之间进行选择,大约为50/50。
这是最后的代码多么简单。
Dim Options = New FirefoxOptions
Options.SetPreference("browser.download.folderList", 2)
'Options.SetPreference("browser.download.dir", "C:\\Windows\\temp")
Options.SetPreference("browser.download.useDownloadDir", True)
Options.SetPreference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream")
Options.SetPreference("pdfjs.disabled", True)
Dim driverService = FirefoxDriverService.CreateDefaultService()
driverService.HideCommandPromptWindow = True
Dim browser = New FirefoxDriver(driverService, Options)
browser.Url = "https://[the website]"
browser.Navigate()
Dim elm = browser.FindElementById("username")
elm.SendKeys([the username])
elm = browser.FindElementById("password")
elm.SendKeys([the password])
elm = browser.FindElementById("loginSubmit")
elm.Click()
While InStr(browser.Url, "token") = 0
Application.DoEvents()
End While
Dim links As IList(Of IWebElement) = browser.FindElementsByPartialLinkText(".")
For Each link As IWebElement In links
link.Click()
Next
我在neverAsk.saveToDisk部分遇到了问题。只是没有用。原来我的哑剧类型错误。我从此评论中得到了解决方案-Set Firefox profile to download files automatically using Selenium and Java