2010-07-18 50 views
14

Tôi đang sử dụng điều khiển WebBrowser trong ứng dụng VB.NET của tôi để tải một vài URL (~ 10-15) và lưu nguồn HTML của chúng trong một tệp văn bản. Tuy nhiên, mã của tôi không viết nguồn của trang hiện tại thay vì mã ban đầu vì nó được kích hoạt ngay cả trước khi trang được tải.Làm thế nào để đợi cho đến khi WebBrowser được tải hoàn toàn trong VB.NET?

Làm cách nào để đợi cho đến khi trang được tải hoàn toàn trước khi gọi bất kỳ sự kiện nào?

Tôi đã thử mã sau nhưng mã không hoạt động.

Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete 
    Application.DoEvents() 
Loop 
+1

Tôi muốn biết điều đó quá. ReadyState thường đạt đến 4 ở giữa tải. Chúng ta chỉ cần biết khi nào nó hoàn thành. Đó là tất cả. –

+0

@shubham nếu bạn vẫn gặp sự cố với điều này, hãy cho tôi biết, vì tôi đã phát triển các kỹ thuật để giải quyết vấn đề này trong những năm qua, các phương pháp chưa được biết và chưa được xuất bản.Vấn đề này là vấn đề quan trọng và khó khăn nhất với toàn bộ điều khiển WebBrowser. Đọc một số bài viết gần đây của tôi kiểm soát webbrowser lại (tôi đã thực hiện nhiều trong vài ngày qua) và đặc biệt là bài viết về những hạn chế của kiểm soát WB, nằm trong bình luận tiếp theo của tôi. Về cơ bản, tôi đã giải quyết tất cả các vấn đề, nếu u vẫn cần giúp đỡ (kể từ khi bài ur là cũ) cho tôi biết và tôi có thể giúp bạn. –

+0

Thảo luận của tôi về những hạn chế của kiểm soát WB, tìm câu trả lời của tôi ở đây: http://stackoverflow.com/questions/1495944/webbrowser-control-limitations/9245591#9245591 –

Trả lời

7

Có vẻ như bạn muốn nắm bắt sự kiện DocumentCompleted điều khiển webbrowser của bạn.

MSDN có một vài bài viết tốt về sự kiểm soát WebBrowser - WebBrowser Class có rất nhiều ví dụ, và How to: Add Web Browser Capabilities to a Windows Forms Application

+0

Trong tuyên bố của WebBrowser bản thân tôi đang sử dụng Private Sub WebBrowser1_DocumentCompleted Làm thế nào tôi có thể thực hiện những gì xảy ra khi trang được tải hoàn toàn bên trong declarion của webbrowser? – Shubham

+0

@Shubham: http://msdn.microsoft.com/en-us/library/k2kt7a7y.aspx (MSDN: "Cách viết: Xử lý sự kiện") hoặc xem ví dụ của Hans. Đừng quên từ khóa 'Handles' ở cuối khai báo phương thức. – Heinzi

+0

** giữ trên ... ** Hãy để tôi đề xuất một ví dụ chính xác về 'DocumentCompleted' từ quan điểm của tôi (xem câu trả lời của tôi) – JCM

19

Salvete! Tôi cần, đơn giản, một chức năng tôi có thể gọi để làm cho mã chờ trang tải trước khi nó tiếp tục. Sau khi cọ rửa trang web để tìm câu trả lời, và không quan tâm trong vài giờ, tôi đã nghĩ ra điều này để giải quyết cho bản thân mình, tình huống khó xử chính xác mà bạn trình bày. Tôi biết tôi đã trễ trong trò chơi với một câu trả lời, nhưng tôi muốn đăng bài này cho bất kỳ ai khác đến cùng.

sử dụng: chỉ cần gọi WaitForPageLoad() chỉ sau một cuộc gọi để chuyển hướng

whatbrowser.Navigate("http://www.google.com") 
WaitForPageLoad() 

một ví dụ khác chúng ta không kết hợp các tính năng điều hướng với tải trang, bởi vì đôi khi bạn cần phải chờ đợi cho một tải mà không cần điều hướng, ví dụ, bạn có thể cần phải chờ một trang để tải được bắt đầu với sự kiện invokemember

whatbrowser.Document.GetElementById("UserName").InnerText = whatusername 
whatbrowser.Document.GetElementById("Password").InnerText = whatpassword 
whatbrowser.Document.GetElementById("LoginButton").InvokeMember("click") 
WaitForPageLoad() 

Đây là mã số: Bạn cần cả hai subs cộng với biến có thể truy cập, pageready. Đầu tiên, hãy chắc chắn để sửa chữa các biến gọi là whatbrowser được kiểm soát WebBrowser của bạn

Bây giờ, ở đâu đó trong mô-đun hoặc lớp học của bạn, đặt này:

Private Property pageready As Boolean = False 

#Region "Page Loading Functions" 
    Private Sub WaitForPageLoad() 
     AddHandler whatbrowser.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter) 
     While Not pageready 
      Application.DoEvents() 
     End While 
     pageready = False 
    End Sub 

    Private Sub PageWaiter(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs) 
     If whatbrowser.ReadyState = WebBrowserReadyState.Complete Then 
      pageready = True 
      RemoveHandler whatbrowser.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter) 
     End If 
    End Sub 

#End Region 
+2

Tôi đã sử dụng mã của bạn để triển khai giải pháp C# tại đây http://stackoverflow.com/questions/11845123/fatal-execution-error-on-browser-readystate/13497611 # 13497611 Cảm ơn !!! –

+2

Bạn được hoan nghênh! Vui vì nó đã giúp một ai đó. – bgmCoder

+2

Tôi đã nhận thấy đây là một trong những bài đăng hữu ích hơn. – MonkeyDoug

3

Về mặt kỹ thuật, có hai vấn đề với mã đăng bởi BGM:

  1. việc thêm trình xử lý trong phương thức WaitForPageLoad có thể quá muộn. Điều hướng được khởi tạo trước khi các trình xử lý được thêm vào có nghĩa là trong các trường hợp rất hiếm khi trình duyệt đã có trang có thể hoàn thành trước khi trình xử lý được thêm vào trong trường hợp đó bạn sẽ bỏ lỡ sự kiện và chờ mãi mãi.

    Giải pháp là để thêm các trình xử lý trước khi chuyển hướng bắt đầu và loại bỏ chúng sau khi chuyển hướng hoàn

    này có nghĩa là phương pháp WaitForPageLoad cần được chia thành hai phương pháp. Một được gọi trước khi bắt đầu điều hướng. Nó nên thiết lập các trình xử lý. Phần thứ hai thực hiện giám sát ReadyState và dọn dẹp khi 'Sẵn sàng'.

  2. thực hành lập trình tốt là thêm một thời gian chờ để trình duyệt bị mất (hay bị rơi, hoặc vòng lặp) không làm cho mã của bạn chờ đợi mãi mãi cho các tài liệu hoàn thành thậm chí

+0

Xin chào! Vâng, tôi đã cố gắng để thực hiện một chức năng mà về cơ bản sẽ "chờ đợi miễn là cần thiết, nếu cần thiết". Tôi nghĩ rằng bạn là đúng, tuy nhiên, có thể (hiếm khi) rằng trang có thể kết thúc tải trước khi xử lý được thêm vào. Tôi chưa trải qua điều đó, nhưng có thể điều đó xảy ra. +1 – bgmCoder

1

tôi vật lộn với này ' nạp đầy đủ 'vấn đề một thời gian nhưng tìm thấy giải pháp sau đây làm việc cho tôi. Tôi đang sử dụng IE7, vì vậy tôi không chắc chắn nếu điều này làm việc trong các phiên bản khác, nhưng đáng xem.

Tôi chia sự cố thành hai phần; đầu tiên tôi cần một thông điệp từ sự kiện DocumentComplete;

Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant) 
    fullyLoaded = True 
End Sub 

Sau đó, trong phần mã nơi tôi cần phải đợi cho đến khi trang web đã được tải đầy đủ, tôi gọi một phụ khác thực hiện điều này;

Private Sub holdBrowserPage() 
    fullyLoaded = False 
    Do While fullyLoaded = False 
     DoEvents 
    Loop 
    fullyLoaded = False 
End Sub 

Ngoài ra, tôi cũng cần làm điều tương tự trong khi chờ mã javascript hoàn tất. Ví dụ trên một trang khi bạn chọn một mục từ danh sách thả xuống html, nó sẽ điền danh sách thả xuống tiếp theo, nhưng phải mất một lúc để tự tiết lộ. Trong trường hợp đó, tôi đã tìm thấy điều này;

Private Sub holdBrowser() 
Do While WebBrowser1.Busy Or WebBrowser1.ReadyState <> READYSTATE_COMPLETE 
    DoEvents 
Loop 
End Sub 

đủ để giữ trình duyệt. Không chắc chắn nếu điều này sẽ giúp tất cả mọi người, như là một sự kết hợp của IE7, trang web tôi đã tải, và javascript rằng các trang đang chạy một mình có thể đã cho phép giải pháp này, nhưng chắc chắn giá trị một thử.

1

Trong sự kiện tải, sử dụng Me.Hide.

Trong WebBrowser1.DocuementCompleted, sử dụng Me.Show

0

Trên thực tế nó là rất dễ dàng, Hãy thử điều này:

While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete 
    Application.DoEvents() 
End While 
0

tôi đã thực hiện chức năng tương tự (chỉ làm việc với tôi) - xin lỗi nó là trong C# nhưng dễ dàng để dịch ...

private void WaitForPageLoad () { 
while (pageReady == false) 
    Application.DoEvents(); 

    while (webBrowser1.IsBusy || webBrowser1.ReadyState != WebBrowserReadyState.Complete) 
    Application.DoEvents(); 
} 
1

Giữ trên ...

Từ kinh nghiệm của tôi, bạn NÊN chắc chắn rằng DocumCompleted thuộc về URL CỦA BẠN chứ không phải một trang phụ, tập lệnh, hình ảnh, CSS, v.v ... Và bất kể IsBusy hoặc ReadyState là xong hay không, cả hai thường không chính xác khi trang hơi phức tạp.

Vâng, đó là trải nghiệm cá nhân của riêng tôi, trên một chương trình làm việc của VB.2013 và IE11. Hãy để tôi cũng đề cập đến rằng bạn nên đưa vào tài khoản cũng là chế độ tương thích IE7 được BẬT theo mặc định tại webBrowser1.

' Page, sub-frame or resource was totally loaded. 
Private Sub webBrowser1_DocumentCompleted(sender As Object, _ 
    e As WebBrowserDocumentCompletedEventArgs) _ 
    Handles webBrowser1.DocumentCompleted 

    ' Check if finally the full page was loaded (inc. sub-frames, javascripts, etc) 
    If e.Url.ToString = webBrowser1.Url.ToString Then 
     ' Only now you are sure! 
     fullyLoaded = True 
    End If 

End Sub 
1

Một số lần nếu bạn sử dụng JavaScript sự kiện DocumentComplet không gửi lại câu trả lời đúng, tôi sử dụng sự kiện này ProgressChanged

Private Sub WebBrowser1_ProgressChanged(sender As Object, e As WebBrowserProgressChangedEventArgs) _ 
Handles WebBrowser1.ProgressChanged 

    Console.WriteLine("CurrentProgress: " + e.CurrentProgress.ToString) 
    If e.CurrentProgress = e.MaximumProgress Then 
     'The maximun progres is reached 
     load_stated = True 
    End If 
    'The page is confirmed downloaded after the pregres return to 0 
    If e.CurrentProgress = 0 Then 
     If load_stated Then 
      'the page is ready to print or download... 
      WebBrowser1.Print() 
      load_stated = False 
     End If 
    End If 
End Sub 
Các vấn đề liên quan