zoukankan      html  css  js  c++  java
  • WebBrowser.Navigate() in loop

         最近在写一个小程序的时候,遇到这样的需求:

              已知一组网页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,下一次循环随即开始执行.
                }
            }

    以上只是笔者在工作中的一点小总结,写出来做个笔记,也希望能给其他人带来一些帮助.相信解决此问题的方法颇多,望不吝赐教...

  • 相关阅读:
    Java8新特性-日期时间
    解决有道云笔记导入md文件无法加载文件内的图片方式
    Mac安装Navicat Premium 12 永久破解
    MacBook Pro安装和配置Tomcat
    MySQL不支持DELETE使用表别名?
    JAVA设计模式之模板方法
    Lombok中的@Builder注解
    JAVA设计模式之策略模式
    Stream中的Peek操作
    MySql插入一条数据不提交事务主键仍自增的理解
  • 原文地址:https://www.cnblogs.com/mxy1028/p/1570888.html
Copyright © 2011-2022 走看看