1. 程式人生 > >net(c#)在迴圈語句中執行WebBrowser.Navigate();方法,每次迴圈等待網頁載入完後繼續執行的解決方案

net(c#)在迴圈語句中執行WebBrowser.Navigate();方法,每次迴圈等待網頁載入完後繼續執行的解決方案

    最近在寫一個小程式的時候,遇到這樣的需求:

          已知一組網頁url地址,想獲取每一個網頁的html,實際上就是想利用迴圈語句裡面使用WebBrowser來載入每一個網頁,然後獲取他們的html,

          要實現這個功能,想想應該是件很簡單的事情,但是在實際操作中卻遇到了問題,因為迴圈語句和WebBrowser的載入不同步的原因,導致前一個

          前一個網頁還沒載入完,下一次迴圈又開始了....最終的結果是WebBrowser只獲取到了最後一個頁面的html.要解決這個問題,我們要做的就是

          讓迴圈執行完前一次後等待網頁載入完,然後執行下一次迴圈去載入下面的網頁.....,按照這個思路,寫了以下程式,經測試果然有效.

  bool  loading  = true ;    // 該變量表示網頁是否正在載入. string  html  = string .Empty;
        WebBrowser browser 
= new  WebBrowser();

        
public void  GetHtml( string [] urls)
        {            
            browser.Navigated 
+= new  WebBrowserNavigatedEventHandler(browser_Navigated);
            
foreach  ( string  url  in  urls)
            {
                loading 
= true ;   // 表示正在載入                   browser.Navigate(url);

                
while  (loading)
                {
                    Application.DoEvents();
// 等待本次載入完畢才執行下次迴圈.                 }
            }
        }

        
void  browser_Navigated( object  sender, WebBrowserNavigatedEventArgs e)
        {
            html 
=  browser.DocumentText;   // 獲取到的html.
            loading 
= false ; // 在載入完成後,將該變數置為false,下一次迴圈隨即開始執行.         }

        上面的問題解決了,下面隨之而來的問題是:  有時候載入一張頁面的時候,browser_Navigated會執行多次.

查了下網上的資料,原因是頁面中含有<iframe></iframe>,每一個<iframe>都會觸發一次browser_Navigated,

所以,以上程式可以完善如下:

bool  loading  = true ;    // 該變量表示網頁是否正在載入. string  html  = string .Empty;
        WebBrowser browser 
= new  WebBrowser();

        
public void  GetHtml( string [] urls)
        {            
            browser.Navigated 
+= new  WebBrowserNavigatedEventHandler(browser_Navigated);
            
foreach  ( string  url  in  urls)
            {
                loading 
= true ;   // 表示正在載入                 browser.Navigate(url);

                
while  (loading)
                {
                    Application.DoEvents();
// 等待本次載入完畢才執行下次迴圈.                 }
            }
        }

        
int  i  = 0 ;
        
void  browser_Navigated( object  sender, WebBrowserNavigatedEventArgs e)
        {
            i
++ ;
            
if  (i  % 3 == 0 //  假設每張頁面要執行3次browser_Navigated方法,那麼這表示網頁全部內容載入完成.(至於這個3要怎麼樣得到,那是仁者見仁的事情了,呵呵)             {
                html 
=  browser.DocumentText;   // 獲取到的html.
                loading 
= false ; // 在載入完成後,將該變數置為false,下一次迴圈隨即開始執行.             }
        }

以上只是筆者在工作中的一點小總結,寫出來做個筆記,也希望能給其他人帶來一些幫助.相信解決此問題的方法頗多,望不吝賜教...

C# webBrowser強制在本視窗開啟,禁止在新視窗開啟

有時需要用WebBrowser載入URL,來實現某些功能。而這時,我們就不希望所開啟的頁面中的連結,在新視窗中開啟,因為這樣的話,實際上是用系統預設的瀏覽器打開了,從而脫離了你的WebBrowser,也就不能被你所控制了。

要解決這個問題,可以使用下面的方法:

假設WebBrowser的Name是 webBrowser

簡單方法-利用載入完成事件將所有的連結和form的target值改為"_seft":

private void webBrowser_DocumentCompleted( object sender, WebBrowserDocumentCompletedEventArgs e)
{
//將所有的連結的目標,指向本窗體
foreach (HtmlElement archor in this .webBrowser.Document.Links)
{
archor.SetAttribute( "target" , "_self" );
}
//將所有的FORM的提交目標,指向本窗體
foreach (HtmlElement form in this .webBrowser.Document.Forms)
{
form.SetAttribute( "target" , "_self" );
}
}

取消新視窗事件

private void webBrowser1_NewWindow( object sender, CancelEventArgs e)
{
e.Cancel = true ;
}

將 WebBrowser 的 AllowWebBrowserDrop 設為 false(禁止拖放)

將 WebBrowser 的 WebBrowserShortcutsEnabled
 設為 false(禁止使用快捷鍵)
將 WebBrowser 的 IsWebBrowserContextMenuEnabled 設為 false
(禁止右鍵上下文選單)