下载直接链接

时间:2015-01-25 05:48:42

标签: vb.net

我的程序一直在使用:

        Dim DLLink1 As String
        DLLink1 = Trim(TextBox2.Text)
        Dim DownloadDirectory1 As String
        DownloadDirectory1 = Trim(TextBox4.Text)
        Try
            Button3.Enabled = False
            '  My.Computer.Network.DownloadFile(DLLink1, (DownloadDirectory1 + "/UpdatedClient.zip"))
            Dim HttpReq As HttpWebRequest = DirectCast(WebRequest.Create(DLLink1), HttpWebRequest)

            Using HttpResponse As HttpWebResponse = DirectCast(HttpReq.GetResponse(), HttpWebResponse)
                Using Reader As New BinaryReader(HttpResponse.GetResponseStream())
                    Dim RdByte As Byte() = Reader.ReadBytes(1 * 1024 * 1024 * 10)
                    Using FStream As New FileStream(DownloadDirectory1 + "/UpdatedClient.zip", FileMode.Create)
                        FStream.Write(RdByte, 0, RdByte.Length)
                    End Using
                End Using
            End Using
        Finally
            MsgBox("Finished Download.")
            Button3.Enabled = True
            Label4.Visible = True

我以前试过这个,但它根本不起作用:

My.Computer.Network.DownloadFile(DLLink1, (DownloadDirectory1 + "/UpdatedClient.zip"))

该网站要求您登录,因此我为该程序创建了一个备用帐户:

WebBrowser1.Navigate("http://www.mpgh.net/forum/admincp/")
    Timer1.Start()
    Button2.Enabled = False

然后

WebBrowser1.Document.GetElementById("vb_login_username").SetAttribute("value", "AutoUpdaterAccount")
    WebBrowser1.Document.GetElementById("vb_login_password").SetAttribute("value", "password")

    Dim allelements As HtmlElementCollection = WebBrowser1.Document.All

    For Each webpageelement As HtmlElement In allelements

        If webpageelement.GetAttribute("type") = "submit" Then

            webpageelement.InvokeMember("click")
            Timer1.Stop()
            Label5.Text = "Authorized."
            Button2.Enabled = True

所以现在你已经登录了网站上的帐户,但是当上面的代码运行时,它会下载一个zip,但它已经损坏了。所以我用notepad++打开它,这就是我得到的(这是否意味着它没有登录下载,它只用webbrowser登录,它们没有链接?或者什么?喜欢我的Firefox登录没有与chrome链接?:

代码很大,就像HTML编码一样。这是我在网上记事本的链接: http://shrib.com/nCOucdfL

另外一件事,一个webbrowser无法在节目上显示,它可以在外面不显示,就像我登录时那样。当弹出一个窗口时,他们也无法像在普通网页浏览器上那样点击保存按钮,我希望它使用一个按钮将目录设置为DownloadDirectory1

,自动下载到他们设置的位置

1 个答案:

答案 0 :(得分:0)

这一定是你的幸运日,因为今天我醒来后决定愿意帮助你解决你的事业。我首先尝试使用Web浏览器控件进行下载,但不幸的是,我确信如果不扩展Web浏览器控件并且我们今天不想这样做,这是不可能的。

正如我在评论中提到的,我真正知道这是可能的(没有用户交互)的唯一方法是通过HttpWebRequest方法登录。这是非常棘手的事情。绝对不适合初学者。

现在我必须承认,这不是最干净,最“适当”和用户友好的代码,所以如果有人想建议一个更好的方法来做事,我很满意。

我建议您先将其测试,然后再将其合并到现有应用中。只需创建一个新的vb.net应用程序,并使用下面的代码替换Form1中的所有代码。您必须使用真实的用户名和密码更新usernameherepasswordhere字符串。此外,默认情况下文件保存为C:\file.rar,因此您可以根据需要更改此路径。此代码完全消除了对Web浏览器控件的需要(除非您将其用于其他内容),因此一旦您正确合并它,您很可能会将其从实际应用程序中删除:

Imports System.Net
Imports System.IO
Imports System.Text

Public Class Form1
    Private Const gsUserAgent As String = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0"

    Const sUsername As String = "usernamehere"
    Const sPassword As String = "passwordhere"
    Const sMainURL As String = "http://www.mpgh.net/"
    Const sCheckLoginURL As String = "http://www.mpgh.net/forum/login.php?do=login"
    Const sDownloadURL As String = "http://www.mpgh.net/forum/attachment.php?attachmentid=266579&d=1417312178"
    Const sCookieLoggedInMessage As String = "mpgh_imloggedin=yes"

    Dim oCookieCollection As CookieCollection = Nothing
    Dim sSaveFile As String = "c:\file.rar"

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        StartScrape()
    End Sub

    Private Sub StartScrape()
        Try
            Dim bContinue As Boolean = True

            Dim sPostData(15) As String

            sPostData(0) = UrlEncode("vb_login_username")
            sPostData(1) = UrlEncode(sUsername)
            sPostData(2) = UrlEncode("vb_login_password")
            sPostData(3) = UrlEncode(sPassword)
            sPostData(4) = UrlEncode("vb_login_password_hint")
            sPostData(5) = UrlEncode("Password")
            sPostData(6) = UrlEncode("s")
            sPostData(7) = UrlEncode("")
            sPostData(8) = UrlEncode("securitytoken")
            sPostData(9) = UrlEncode("guest")
            sPostData(10) = UrlEncode("do")
            sPostData(11) = UrlEncode("login")
            sPostData(12) = UrlEncode("vb_login_md5password")
            sPostData(13) = UrlEncode("")
            sPostData(14) = UrlEncode("vb_login_md5password_utf")
            sPostData(15) = UrlEncode("")

            If GetMethod(sMainURL) = True Then
                If SetMethod(sCheckLoginURL, sPostData, sMainURL) = True Then
                    ' Login successful

                    If DownloadMethod(sDownloadURL, sMainURL) = True Then
                        MessageBox.Show("File downloaded successfully")
                    Else
                        MessageBox.Show("Error downloading file")
                    End If
                End If
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try
    End Sub

    Private Function GetMethod(ByVal sPage As String) As Boolean
        Dim req As HttpWebRequest
        Dim resp As HttpWebResponse
        Dim stw As StreamReader
        Dim bReturn As Boolean = True

        Try
            req = HttpWebRequest.Create(sPage)
            req.Method = "GET"
            req.AllowAutoRedirect = False
            req.UserAgent = gsUserAgent
            req.Accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
            req.Headers.Add("Accept-Language", "en-us,en;q=0.5")
            req.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
            req.Headers.Add("Keep-Alive", "300")
            req.KeepAlive = True

            resp = req.GetResponse        ' Get the response from the server 

            If req.HaveResponse Then
                ' Save the cookie info if applicable
                SaveCookies(resp.Headers("Set-Cookie"))

                resp = req.GetResponse        ' Get the response from the server 
                stw = New StreamReader(resp.GetResponseStream)
                stw.ReadToEnd()    ' Read the response from the server, but we do not save it
            Else
                MessageBox.Show("No response received from host " & sPage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                bReturn = False
            End If
        Catch exc As WebException
            MessageBox.Show("Network Error: " & exc.Message.ToString & " Status Code: " & exc.Status.ToString & " from " & sPage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            bReturn = False
        End Try

        Return bReturn
    End Function

    Private Function SetMethod(ByVal sPage As String, ByVal sPostData() As String, sReferer As String) As Boolean
        Dim bReturn As Boolean = False
        Dim req As HttpWebRequest
        Dim resp As HttpWebResponse
        Dim str As StreamWriter
        Dim sPostDataValue As String = ""

        Try
            req = HttpWebRequest.Create(sPage)
            req.Method = "POST"
            req.UserAgent = gsUserAgent
            req.Accept = "application/x-shockwave-flash,text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
            req.Headers.Add("Accept-Language", "en-us,en;q=0.5")
            req.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7")
            req.Referer = sReferer
            req.ContentType = "application/x-www-form-urlencoded"
            req.Headers.Add("Pragma", "no-cache")
            req.Headers.Add("Keep-Alive", "300")

            If oCookieCollection IsNot Nothing Then
                ' Pass cookie info from the login page
                req.CookieContainer = SetCookieContainer(sPage)
            End If

            str = New StreamWriter(req.GetRequestStream)

            If sPostData.Count Mod 2 = 0 Then
                ' There is an even number of post names and values

                For i As Int32 = 0 To sPostData.Count - 1 Step 2
                    ' Put the post data together into one string
                    sPostDataValue &= sPostData(i) & "=" & sPostData(i + 1) & "&"
                Next i

                sPostDataValue = sPostDataValue.Substring(0, sPostDataValue.Length - 1) ' This will remove the extra "&" at the end that was added from the for loop above

                ' Post the data to the server

                str.Write(sPostDataValue)
                str.Close()

                ' Get the response

                resp = req.GetResponse

                If req.HaveResponse Then
                    If resp.Headers("Set-Cookie").IndexOf(sCookieLoggedInMessage) > -1 Then
                        ' Save the cookie info
                        SaveCookies(resp.Headers("Set-Cookie"))
                        bReturn = True
                    Else
                        MessageBox.Show("The email or password you entered are incorrect." & vbCrLf & vbCrLf & "Please try again.", "Unable to log in", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                        bReturn = False
                    End If
                Else
                    ' This should probably never happen.. but if it does, we give a message
                    MessageBox.Show("The email or password you entered are incorrect." & vbCrLf & vbCrLf & "Please try again.", "Unable to log in", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                    bReturn = False
                End If
            Else
                ' Did not specify the correct amount of parameters so we cannot continue
                MessageBox.Show("POST error.  Did not supply the correct amount of post data for " & sPage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                bReturn = False
            End If
        Catch ex As Exception
            MessageBox.Show("POST error.  " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            bReturn = False
        End Try

        Return bReturn
    End Function

    Private Function DownloadMethod(ByVal sPage As String, sReferer As String) As Boolean
        Dim req As HttpWebRequest
        Dim bReturn As Boolean = False

        Try
            req = HttpWebRequest.Create(sPage)
            req.Method = "GET"
            req.AllowAutoRedirect = False
            req.UserAgent = gsUserAgent
            req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
            req.Headers.Add("Accept-Language", "en-US,en;q=0.5")
            req.Headers.Add("Accept-Encoding", "gzip, deflate")
            req.Headers.Add("Keep-Alive", "300")
            req.KeepAlive = True

            If oCookieCollection IsNot Nothing Then
                ' Set cookie info so that we continue to be logged in
                req.CookieContainer = SetCookieContainer(sPage)
            End If

            ' Save file to disk

            Using oResponse As System.Net.WebResponse = CType(req.GetResponse, System.Net.WebResponse)
                Using responseStream As IO.Stream = oResponse.GetResponseStream
                    Using fs As New IO.FileStream(sSaveFile, FileMode.Create, FileAccess.Write)
                        Dim buffer(2047) As Byte
                        Dim read As Integer

                        Do
                            read = responseStream.Read(buffer, 0, buffer.Length)
                            fs.Write(buffer, 0, read)
                        Loop Until read = 0

                        responseStream.Close()
                        fs.Flush()
                        fs.Close()
                    End Using

                    responseStream.Close()
                End Using

                oResponse.Close()
            End Using

            bReturn = True
        Catch exc As WebException
            MessageBox.Show("Network Error: " & exc.Message.ToString & " Status Code: " & exc.Status.ToString & " from " & sPage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            bReturn = False
        End Try

        Return bReturn
    End Function

    Private Function SetCookieContainer(sPage As String) As System.Net.CookieContainer
        Dim oCookieContainerObject As New System.Net.CookieContainer
        Dim oCookie As System.Net.Cookie

        For c As Int32 = 0 To oCookieCollection.Count - 1
            If IsDate(oCookieCollection(c).Value) = True Then
                ' Fix dates as they seem to cause errors/problems
                oCookieCollection(c).Value = Format(CDate(oCookieCollection(c).Value), "dd-MMM-yyyy hh:mm:ss")
            End If

            oCookie = New System.Net.Cookie
            oCookie.Name = oCookieCollection(c).Name
            oCookie.Value = oCookieCollection(c).Value
            oCookie.Domain = New Uri(sPage).Host
            oCookie.Secure = False
            oCookieContainerObject.Add(oCookie)
        Next

        Return oCookieContainerObject
    End Function

    Private Sub SaveCookies(sCookieString As String)
        Dim sCookieStrings() As String = sCookieString.Trim.Replace(" HttpOnly,", "").Replace(" HttpOnly", "").Replace(" domain=.mpgh.net,", "").Split(";".ToCharArray())

        oCookieCollection = New CookieCollection

        For Each sCookie As String In sCookieStrings
            If sCookie.Trim <> "" Then
                Dim sName As String = sCookie.Trim().Split("=".ToCharArray())(0)
                Dim sValue As String = sCookie.Trim().Split("=".ToCharArray())(1)

                oCookieCollection.Add(New Cookie(sName, sValue))
            End If
        Next
    End Sub

    Private Function UrlEncode(ByRef URLText As String) As String
        Dim AscCode As Integer
        Dim EncText As String = ""
        Dim bStr() As Byte = Encoding.ASCII.GetBytes(URLText)

        Try
            For i As Long = 0 To UBound(bStr)
                AscCode = bStr(i)

                Select Case AscCode
                    Case 48 To 57, 65 To 90, 97 To 122, 46, 95
                        EncText = EncText & Chr(AscCode)

                    Case 32
                        EncText = EncText & "+"

                    Case Else
                        If AscCode < 16 Then
                            EncText = EncText & "%0" & Hex(AscCode)
                        Else
                            EncText = EncText & "%" & Hex(AscCode)
                        End If

                End Select
            Next i

            Erase bStr
        Catch ex As WebException
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

        Return EncText
    End Function
End Class