net(c#)在循环语句中执行WebBrowser.Navigate();方法,每次循环等待网页加载完后继续执行的解决方案

46 篇文章 0 订阅
    最近在写一个小程序的时候,遇到这样的需求:

          已知一组网页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
(禁止右键上下文菜单)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值