zoukankan      html  css  js  c++  java
  • C# winform调用WebBrowser经典怪问题总结

    C# winform调用WebBrowser经典怪问题总结

    最近一直研究网页数据采集,单单采集数据,其实HtmlAgilityPack就足够了。

    对HtmlAgilityPack感兴趣的可以到这里看看:C#采集代理服务器ip并设置IE代理--HtmlAgilityPack实战代码 
    但是有个问题:要是想要模拟人工输入数据,进行表单提交HtmlAgilityPack就办不了,Skybound.Gecko(firfox的.net开源代码)

    也办不了这个事情。Skybound.Gecko不支持点击,不知道大家有没有新的方法。

    反正我只能用微软自带的WebBrowser来模拟网页点击了。

    刚开始一切正常,但是随着功能增加,有几个问题就出来了。下面一一列出,并给出基本解决办法。

    1) 屏蔽脚本错误对话框

    解决办法:

    复制代码
    webBrowser1.ScriptErrorsSuppressed = true;//我经常设置成false。汗颜啊 。
    复制代码


    2.屏蔽Js弹出框(能够屏蔽conform的)

    C# webbrowser弹出框

    一定要写在你提交事件之前!

    复制代码
     IHTMLDocument2 vDocument = (IHTMLDocument2)webBrowser1.Document.DomDocument;
     vDocument.parentWindow.execScript("function confirm(str){return true;} ", "javascript"); //弹出确认
     vDocument.parentWindow.execScript("function alert(str){return true;} ", "javaScript");//弹出提示
      element.InvokeMember("click");//element是我需要的提交按钮
    复制代码

    3.WebBrowser的DocumentCompleted执行多次的原因(包含多个iframe造成的)

    情况1、WebBrowser载入一个页面后DocumentCompleted事件会执行两次,
    但这两次的ReadyState状态不一样,分别是Intercative和Complete。
    而MSDN对这两种状态值的解释是:
    Complete该控件已完成新文档及其所有内容的加载;
    Interactive该控件已经加载足够的文档以允许有限的用户交互,比如单击已显示的超链接。
    由此可见,实际上DocumentCompleted事件会在Interactive状态和Complete状态各调用一次,
    那么我们可以根据我们的需要来判断到底需要那一次。解决办法实例代码如下:
    复制代码
    if(webBrowser1.ReadyState!=WebBrowerReadyState.Complete)
        return;
    复制代码


    情况2、如果一个页面中含有多个框架页Iframes,那么在每个框架页加载完成时也可能触发一次DocumentCompleted事件
    MSDN对其解释是在多个的帧的情况下DocumentComplete获取触发多次。
    并非每个框架将触发此事件,但触发DownloadBegin事件的每个框架将触发相应的DocumentComplete事件。
    这种情况下解决办法实例代码如下:
    复制代码
    if(e.Url.ToString()!=webBrowser1.Url.ToString())
        return;
    复制代码

    4.彻底解决弹出问题:方法2中说明的代码,解决弹出一次对话框的问题,如果连续弹出conform和alert就会失效。

    最后终极方法:就是继承WebBrowser,屏蔽掉弹出框事件,或者加上你自己的处理方法。

    这是一个治本的方法。也不是很复杂。

    建立一个类,继承自System.Windows.Forms.WebBrowser。

    直接下载地址:http://pan.baidu.com/share/link?shareid=1906864666&uk=1765114824

    复制代码
     View Code

    public class MyWebBrowser : System.Windows.Forms.WebBrowser
    {
    #region ExtendedWebBrowserSite
    class ExtendedWebBrowserSite : WebBrowser.WebBrowserSite, UnsafeNativeMethods.IDocHostShowUI
    {
    public ExtendedWebBrowserSite(WebBrowser host)
    : base(host)
    {
    }
    void UnsafeNativeMethods.IDocHostShowUI.ShowMessage(ref UnsafeNativeMethods._RemotableHandle hwnd, string lpstrText, string lpstrCaption, uint dwType, string lpstrHelpFile, uint dwHelpContext, out int plResult)
    {
    plResult = 0;
    //TODO:自定义
    }
    void UnsafeNativeMethods.IDocHostShowUI.ShowHelp(ref UnsafeNativeMethods._RemotableHandle hwnd, string pszHelpFile, uint uCommand, uint dwData, UnsafeNativeMethods.tagPOINT ptMouse, object pDispatchObjectHit)
    {
    //TODO:自定义
    }
    }

    protected override WebBrowserSiteBase CreateWebBrowserSiteBase()
    {
    return new ExtendedWebBrowserSite(this);
    }
    #endregion
    }

    public class UnsafeNativeMethods
    {
    #region IDocHostShowUI
    [StructLayout(LayoutKind.Explicit, Pack = 4)]
    public struct __MIDL_IWinTypes_0009
    {
    // Fields
    [FieldOffset(0)]
    public int hInproc;
    [FieldOffset(0)]
    public int hRemote;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct _RemotableHandle
    {
    public int fContext;
    public __MIDL_IWinTypes_0009 u;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct tagPOINT
    {
    public int x;
    public int y;
    }

    [ComImport, Guid("C4D244B0-D43E-11CF-893B-00AA00BDCE1A"), InterfaceType((short)1)]
    public interface IDocHostShowUI
    {
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
    void ShowMessage([In, ComAliasName("ExtendedWebBrowser2.UnsafeNativeMethods.wireHWND")] ref _RemotableHandle hwnd, [In, MarshalAs(UnmanagedType.LPWStr)] string lpstrText, [In, MarshalAs(UnmanagedType.LPWStr)] string lpstrCaption, [In] uint dwType, [In, MarshalAs(UnmanagedType.LPWStr)] string lpstrHelpFile, [In] uint dwHelpContext, [ComAliasName("ExtendedWebBrowser2.UnsafeNativeMethods.LONG_PTR")] out int plResult);
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
    void ShowHelp([In, ComAliasName("ExtendedWebBrowser2.UnsafeNativeMethods.wireHWND")] ref _RemotableHandle hwnd, [In, MarshalAs(UnmanagedType.LPWStr)] string pszHelpFile, [In] uint uCommand, [In] uint dwData, [In] tagPOINT ptMouse, [Out, MarshalAs(UnmanagedType.IDispatch)] object pDispatchObjectHit);
    }
    #endregion

    }

    复制代码

    WebBrowser说实话潜规则太多,没办法才用他。苦逼啊。

    如果对你有帮助,请点击推荐哦。

     
     
     
  • 相关阅读:
    Spring Data JPA 入门篇
    44444444444444444444444444444444dddddddddd66666666666666666666666666
    1111111111111
    第二个随笔啊
    我的第一个Node web程序
    centos 6 不能上网
    开通博客园
    【转载】【超详细教程】使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结
    Ajax返回值之XML、json类型
    XHR详细讨论
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3277368.html
Copyright © 2011-2022 走看看