专业网站建设品牌,十四年专业建站经验,服务6000+客户--广州京杭网络
免费热线:400-963-0016      微信咨询  |  联系我们

C#多线程处理webbrowser及InvokeMember("click")无响应的问题

当前位置:网站建设 > 技术支持
资料来源:网络整理       时间:2023/2/14 0:10:02       共计:3641 浏览

文章重点:多线程处理webbrowser的相关问题,并解决触发click事件,js无响应问题

最近刚好碰上一个需求:循环遍历网页元素,找到innerText为指定的内容时,就模拟人工点击

解决办法:使用WebBrowser将指定位置的文档加载到 WebBrowser 控件中(注:这里的webbrowser是在拉控件的方式,而不是直接在代码中new)

源码如下:

private void loadPage(object URL)
        { try { string url = (string)URL;               
                browser.Navigate(url); while (true)
                {
                   Application.DoEvents(); if(browser.ReadyState != WebBrowserReadyState.Complete) 
                  { break;
                   }
                }                                
                HtmlDocument document = browser.Document;
                HtmlElementCollection elems = browser.Document.GetElementsByTagName("a"); foreach (HtmlElement em in elems)
                { if (em.InnerText == "测试")
                    {          
                        em.InvokeMember("click");//"触发点击事件"  }
                }
            } catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        } 

有一点没说到,上面的只适合单线程的,如果执行以上代码的是在新开辟的一个线程中的话,会碰到一系列的问题......(很遗憾,我没有将那些问题 记录下来,但相信如果你跟我有着同样的需求的话,即采用多线程的方式处理webbrowser加载的网页内容的话,可以继续看下去,也许对你有所帮助)

网上一搜,关于webbrowser在多线程中的使用着实会碰到很多问题……后来,经过自己不断的Google(在这过程中你能体会到百度离Google还有多远),有找到了几篇对我有所帮助的文章:

关于线程的知识:http://www.cnblogs.com/JimmyZheng/archive/2012/06/10/2543143.html

WebBrowser多线程带来的麻烦:http://www.cnblogs.com/xjfhnsd/archive/2010/03/14/1685441.html

WebBrowser 显示Html内容3点细节技巧: http://www.cnblogs.com/cyq1162/archive/2012/03/27/2419655.html

 

接着,我就使用webclient配合webbrowser从而顺利的解决了问题。

WebClient:下载指定网址的源码

WebBrowser:navigate一个空白页(具体参考:)

注:这里的WebBrowser要从代码中new,如果是拉控件的方式创建的,将会报错:"指定的转换无效"

这里我就写一个以上列出的文章所没有提到的。

比如,我们要click的网页元素是通过js来触发的,而使用webclient只能下载指定的url的网页源码,无法自动加载相关的js,因此导致在使用invokeMember("click")的时候,没能见到预期效果。

解决办法:将指定的js文件也下载下来(或者将需要用到的js方法放到本地,使用webclient  载入进来也行)

我这里说的只是一个大题的思路和解决途径

最后,贴上一段测试代码:

C#源码:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; using System.Net; namespace webbrowser控件
{ public partial class Form1 : Form
    { public Form1()
        {
            InitializeComponent();
        } private void button1_Click(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            ParameterizedThreadStart pt;
            pt = new ParameterizedThreadStart(loadPage);
            Thread td = new Thread(pt);
            td.Name = "主线程";
            td.SetApartmentState(ApartmentState.STA);//在线程启动前设置其单元状态 td.Start("http://127.0.0.1/test.html");            
        } private void loadPage(object URL)
        { try { string url = (string)URL;
                WebBrowser browser = new WebBrowser();//当前线程不在单线程单元中,因此无法实例化 ActiveX 控件 browser.ScriptErrorsSuppressed = true; //browser.Navigate(url); //browser.DocumentCompleted += browser_DocumentCompleted; browser.Navigate("about:blank"); string htmlcode = GetHtmlSource(url); string js = GetHtmlSource("http://127.0.0.1/MY/test/js.html");//载入js  browser.Document.Write(js);  
                textBox1.Text = htmlcode; //while (browser.ReadyState != WebBrowserReadyState.Complete) //报错“指定的转换无效” // Application.DoEvents();  browser.Document.Write(htmlcode); //MessageBox.Show(browser.DocumentText); HtmlDocument document = browser.Document;
                HtmlElementCollection elems = browser.Document.GetElementsByTagName("a"); foreach (HtmlElement em in elems)
                { if (em.InnerText == "点击")
                    {          
                        em.InvokeMember("click");//alert("触发点击事件")  }
                }
            } catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            } finally { //MessageBox.Show("当前执行线程:"+Thread.CurrentThread.Name);  }
        } //WebClient取网页源码 private string GetHtmlSource(string Url)
        { string text1 = ""; try {
                WebClient wc = new WebClient();

                text1 = wc.DownloadString(Url);
            } catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            } return text1;
        }

    }
}

test.html:

<html> <head> <title></title> <script type="text/javascript" src="a.js"></script> </head> <body> <a href="javascript:void();" onclick="t()">点击</a> </body> </html>

js:

<script type="text/javascript"> function t()
{
    alert('ddd');
} </script>

原创文章,转载请注明出处:http://www.cnblogs.com/hongfei/archive/2013/01/05/2846933.html

版权说明:
本网站凡注明“广州京杭 原创”的皆为本站原创文章,如需转载请注明出处!
本网转载皆注明出处,遵循行业规范,如发现作品内容版权或其它问题的,请与我们联系处理!
欢迎扫描右侧微信二维码与我们联系。
·上一条:ASP.Net WebBrowser页面与WinForm交互技巧 | ·下一条:C# 数据采集webBrowser控件获取js动态创建的元素

Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有    粤ICP备16019765号 

广州京杭网络科技有限公司 版权所有