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

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
 
    }
View Code

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]中提到了在VS2005中使用WebBrowser控件的简单应用,但是没有具体提到如何修改字体。引用\[2\]中提到了在WPF中嵌入WinForm中的WebBrowser控件,但同样没有提到如何修改字体。引用\[3\]中提到了使用JavaScript来修改字体的方法,但是这种方法不推荐使用。根据提供的引用内容,没有明确的方法来修改WebBrowser控件中的字体。 如果你想在C#中修改WebBrowser控件中的字体,可以尝试使用JavaScript来实现。你可以通过调用WebBrowser控件的Document属性来获取网页的DOM对象,然后使用JavaScript来修改字体样式。例如,你可以使用以下代码来修改字体大小和行高: ```csharp webBrowser1.Document.InvokeScript("execScript", new object\[\] { "document.body.style.fontSize = '16px'; document.body.style.lineHeight = '1.5';", "JavaScript" }); ``` 这段代码会将字体大小设置为16像素,行高设置为1.5倍。你可以根据需要修改这些值来实现你想要的效果。 请注意,这种方法只适用于加载了网页内容的WebBrowser控件,对于本地HTML文件可能会有一些限制。另外,使用JavaScript来修改字体可能会影响网页的布局和样式,所以请谨慎使用。 #### 引用[.reference_title] - *1* *2* [C#中实现WebBrowser控件的HTML源代码读写](https://blog.csdn.net/weixin_29416629/article/details/117833349)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [关于webbrowser更改字体大小的方法](https://blog.csdn.net/weixin_30740295/article/details/96554205)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值