天天看點

vb.net利用webbrowser下載下傳(加載完成判斷、多線程、委托)

下載下傳一個電子書籍,每頁有圖檔,多個圖檔就是整個教材的頁數。

流程:利用webbrowser來判斷網頁加載完成,對網頁代碼用正則提取對應的書頁實際位址。逐個下載下傳每個書頁到一個檔案夾。

問題:webbrowser在判斷加載完成時出現困難。

          1.完成狀态無法使用。wb.ReadyState = WebBrowserReadyState.Complete根本不起作用。

          2.網頁是否繁忙(Not wb.IsBusy)起作用,但同類網頁激活次數不一,有些2次,有些3次,還有些4次。無法判斷哪一次最終加載完成。

          3.合并狀态也無法判斷加載完成:If Not wb.IsBusy And wb.ReadyState = WebBrowserReadyState.Complete Then

初步解決:

    為了了解到底是哪個因素對加載完成起标志作用,在原程式中加入一個清單框(用來看網頁加載完成進入時的資訊)。

      利用Listbox1.Items.add(e.GetType.Tostring & "=" & e.Url.Tostring)來觀察每次進入加載完成的資訊情況。

      終于發現e.Url.Tostring有變化情況。主要由一個googlead和api.uyan的變化,前者次數不确定,由1-3次組成;後者每次網頁必定隻加載一次。

     于是,判斷網頁加載完成由api.uyan來決定(不同網頁網址不同)。删除listbox完成本次小程式。

程式界面:

vb.net利用webbrowser下載下傳(加載完成判斷、多線程、委托)

完整源代碼:

Imports System.Text.RegularExpressions

Public Class Form1
    Dim mythread As Threading.Thread
    Dim strHead As String  '首網頁前頭部分
    Dim intPage As Int32   '頁數計數
    Dim intPageCur As Int32
    Dim strDownWeb As String
    Dim flag As String = "complete" '完成情況,預設完成
    Dim intCount As Int32
    Dim intMax As Int32
    '委托
    Private Delegate Sub voidShowMessage(ByVal strMessage As String)

    Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
        '對連續使用時,變量清空
        strHead = ""
        flag = "complete"
        intCount = 0

        '提取首頁頭部
        Dim a() As String, i As Int32
        If txtFirstWeb.Text = "" Then
            MsgBox("網址錯誤")
            Exit Sub
        End If
        a = Split(txtFirstWeb.Text, "/")
        If a.GetUpperBound(0) < 3 Then
            MsgBox("網址錯誤")
            Exit Sub
        End If
        strHead = ""
        For i = 0 To a.GetUpperBound(0) - 1
            strHead = strHead & a(i) & "/"
        Next
        intPage = 1

        wb.Navigate(strHead & intPage.ToString("000") & ".htm")
        'wb.Navigate("http://www.dzkbw.com/books/rjb/yuwen/pc7x/271.htm")
    End Sub

    Private Sub wb_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles wb.DocumentCompleted
        If InStr(e.Url.ToString, "api.uyan") > 0 Then
            Dim strAllCode As String = wb.DocumentText
            Dim reg As Regex

            intCount = intCount + 1
            If intCount = 1 Then
                reg = New Regex("(?<=maxPage=)\d{1,3}(?=;)")
                intMax = reg.Matches(strAllCode)(0).Value
            End If

            reg = New Regex("(?<=img[ ]{1,3}src="").*?.jpg(?=""[ ]{1,3}id=""ebookimg)")
            If reg.Matches(wb.DocumentText).Count > 0 Then
                strDownWeb = reg.Matches(strAllCode)(0).Value
                Do While flag = "down" '等待下載下傳完成
                    Application.DoEvents()
                Loop
                flag = "down"
                mythread = New Threading.Thread(AddressOf DownFile)
                intPageCur = intPage
                mythread.Start(strDownWeb)

                reg = Nothing
                Do While flag = "down" '等待下載下傳完成
                    Application.DoEvents()
                Loop
                If flag = "complete" Then
                    If intPage >= intMax Then
                        lblState.Text = "狀态:已完成!"
                        Exit Sub
                    Else
                        intPage = intPage + 1
                        wb.Navigate(strHead & intPage.ToString("000") & ".htm")
                    End If
                End If
            End If
        End If

    End Sub

    Private Sub DownFile(ByVal strweb As String)
        Try
            My.Computer.Network.DownloadFile(strweb, "D:\School\" & intPageCur.ToString("000") & ".jpg")
            Me.Invoke(New voidShowMessage(AddressOf ShowMessage), "狀态:下載下傳第" & intPageCur.ToString("000") & "頁")
            'Me.Invoke(New voidShowMessage(AddressOf ShowMessage), strweb)
        Catch ex As Exception
            Me.Invoke(New voidShowMessage(AddressOf ShowMessage), "狀态:第" & intPageCur.ToString("000") & "頁下載下傳失敗." & ex.Message)
        End Try

        flag = "complete"
        mythread.Abort()
    End Sub

    Private Sub ShowMessage(ByVal m As String)
        lblState.Text = m
    End Sub
End Class