winform使用CefSharp嵌入浏览器

网上大部分教程的都是使用Nuget下载CefSharp,但是我试了一下,下载速度慢得要命,折腾了好久都没有下载成功,最后只好下载别人提供好的压缩包

同时,使用CefSharp有几个特别注意的地方:

1   你要安装VC ++ Runtime 2013,不然会报  ‘无法加载文件或’CefSharp.Core.dll’程序集或它的一个依赖’ 的错误,下载地址:

  https://www.microsoft.com/zh-CN/download/details.aspx?id=40784

2  设置项目对应的解决方案设置目标平台为x86或者x64

3  根据你的系统下载32位或者64位的CefSharp,当然你可以使用vistual studio的包管理工具Nuget下载,我这里提供压缩包版下载地址,解压就可以使用,免费并免积分,如果那天需要积分了,请告知我一声,我调回来,有时候csdn那边会乱调我的资源所需的积分值

64位:https://download.csdn.net/download/zxy13826134783/12277612

32位:https://download.csdn.net/download/zxy13826134783/12277907

首先介绍一下我的开发环境:

vistual studio 2012

window 7

.net framework 4.6 (查阅资料发现有人说CefSharp与.net framework的版本有很大的关系,我测试发现使用vistual studio 2019可以下载最新版CefSharp,而且是把项目对应的解决方案设置目标平台为x86或者x64后才能下载,但到导入项目时出现诡异的警告,运行报错,最后不得不下载别人提供压缩包版的)

详细步骤如下:

1  先安装VC ++ Runtime 2013

2  新建一个winform项目,名为CefSharpDemo1

3   设置项目对应的解决方案设置目标平台为x86或者x64,下面动图是以64位作为演示

4   解压下载好的CefSharp,并在项目中添加下面三个dll(就在解压后的文件夹内)引用:

CefSharp.dll

CefSharp.Core.dll

CefSharp.WinForms.dll

5  把解压后的所有文件拷贝到bin/Debug的目录下(注意是x64那个文件夹内的Debug目录,如果是32位系统,则为x86那个文件夹),具体步骤如下动图:

6  在默认新建的窗体Form1编写代码如下:

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;

namespace CefSharpDemo1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitBrowser();
        }

        public CefSharp.WinForms.ChromiumWebBrowser browser;
        public void InitBrowser()
        {
            CefSharp.Cef.Initialize(new CefSharp.CefSettings());
            browser = new CefSharp.WinForms.ChromiumWebBrowser("www.baidu.com");
            this.Controls.Add(browser);
            browser.Dock = DockStyle.Fill;

        }
    }
}

最终运行效果如下动图所示:

2020年6月2日补充:

与javascript进行交互,可实现模拟键盘输入或者鼠标点击操作

//其它初始化操作省略...

public CefSharp.WinForms.ChromiumWebBrowser browser=new CefSharp.WinForms.ChromiumWebBrowser(url);

//为网页中id号为input J_Input的输入控件设置值

browser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("document.getElementById('input J_Input').value='设置的值'")

//模拟鼠标点击,模拟鼠标点击classname为btn J_Submit的控件

browser.GetBrowser().MainFrame.ExecuteJavaScriptAsync("document.getElementsByClassName('btn J_Submit')[0].click();")

执行javascript方法,获取网页html代码

方法1:获取当前页面html源码,同步完成

 //初始化代码省略...
 public CefSharp.WinForms.ChromiumWebBrowser browser;


private async void btnNext_Click(object sender, EventArgs e){
    //注意,下面一行代码需要放在带async关键字的方法内
    string html = await browser.GetBrowser().MainFrame.GetSourceAsync();
}
 

方法2:网页加载完毕后自动获取,有点问题,在获取淘宝的html源码时,发现注册的方法回调多次,


//注册网页加载完毕后回调的方法,其它初始化代码省略...
browser.FrameLoadEnd+=browser_FrameLoadEnd;



private void browser_FrameLoadEnd(object sender, CefSharp.FrameLoadEndEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("function tempFunction() {");
            sb.AppendLine(" return document.getElementsByTagName('html')[0].innerHTML; ");
            sb.AppendLine("}");
            sb.AppendLine("tempFunction();");
            var task01 = browser.GetBrowser().MainFrame.EvaluateScriptAsync(sb.ToString());
            task01.ContinueWith(t =>
            {
                if (!t.IsFaulted)
                {
                    var response = t.Result;
                    if (response.Success == true)
                    {
                        if (response.Result != null)
                        {
                            
                            string html = response.Result.ToString();
                           
                        }
                    }
                }
            });
        }

2020年6月6日补充:

案例:抓取淘宝数据,并获取每个商品的历史最高价、历史最低价和现价,帮助用户快速找到那个商品最值得买

案例视频演示地址:淘宝购物助手_哔哩哔哩_bilibili

案例项目源码地址下载:淘宝商品推荐.rar · 张祥裕/分享的资源名称 - Gitee.com

核心知识点

1  网页源码html的获取

2  使用正则表达式解析html并获取到需要的信息

3   CefSharp与JavaScrtipt交互,模拟键盘输入和鼠标点击(文章前面已经讲述,不再叙述)

网页源码html的获取涉及到

1  请求的方式是POST还是GET请求;

2  是否需要ip代理,请求某些网站重要的数据是需要ip代理,不然会被识别为爬虫

3  请求方式为POST请求时,是否需要发送表单数据

下面的代码是获取网站的html源码,需要ip代理并根据设置并发送表单数据:

   /// <summary>
        /// 获取网页的源码
        /// </summary>
        /// <param name="url">网页url地址</param>
        /// <param name="Method">POST或者GET</param>
        /// <param name="formData">formData的数据,没有填null</param>
        /// <returns></returns>
        public string GetHtml(string url,string Method,Dictionary<string,string> formData)
        {

            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //加上这一句
            Uri uri = new Uri(url);
            HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(uri);
            //设置请求头
            myReq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36";
            myReq.Accept = "*/*";
            myReq.KeepAlive = false;
            myReq.AllowAutoRedirect = true;
            myReq.Headers.Add("Accept-Language", "zh-CN,zh;q=0.9");

            myReq.ContentType = "application/x-www-form-urlencoded;charset=utf-8";

            //设置请求的方式,是POST还是GET请求
            myReq.Method =Method;
            //设置请求的最长时间,毫秒级别,超过这个时间,就算请求失败
            myReq.Timeout = 1000;

            //产生随机数,从List列表中取出代理ip,目的是为了3个ip能轮流请求,这样被识别为爬虫的概率会降低
            Random r = new Random();
            int ramdom=r.Next(1, 4);
            Console.WriteLine(ramdom);


            //设置代理ip,以:分割,如47.84.102.137:1245通过冒号分割后,str[0]="47.84.102.137",str[1]="1245"
            string[] str = Ip_Port_List[ramdom].Split(':');

            string proxyIp =str[0];// str[0];
            int proxyPort =Convert.ToInt32(str[1]);
            //设置代理ip
            myReq.Proxy = new WebProxy(proxyIp, proxyPort);

            //添加表单数据,通过formData来判断是否有表单数据需要提交
            if (formData != null&&formData.Count>0)
            {
                string formDataParam = "";
                int index = 0;
                foreach (var item in formData)
                {
                    //第一个参数一般不需要加&
                    if (index == 0)
                    {
                        formDataParam += item.Key + "=" + item.Value;
                        index++;
                    }
                    else
                    {
                        //从第二个参考开始后就需要加&
                        formDataParam +="&"+item.Key + "=" + item.Value;
                        
                    }
                    //最终formDataParam类似这样:formDataParam=param1=value1&param2=value2&param3=value3
                }
                

                myReq.AllowWriteStreamBuffering = true;
                byte[] buffer = Encoding.UTF8.GetBytes(formDataParam);
                myReq.ContentLength = buffer.Length;
                using (Stream requestStream = myReq.GetRequestStream())
                {

                    requestStream.Write(buffer, 0, buffer.Length);
                    requestStream.Flush();
                }
            }
            HttpWebResponse result;
            try
            {
                result = (HttpWebResponse)myReq.GetResponse();
            }
            catch (Exception)
            {

                return "";
            }

            
            Stream receviceStream = result.GetResponseStream();
            StreamReader readerOfStream = new StreamReader(receviceStream, System.Text.Encoding.GetEncoding("utf-8"));
            string strHTML = readerOfStream.ReadToEnd();
            readerOfStream.Close();
            receviceStream.Close();
            result.Close();
            return strHTML;
        }

使用正则表达式解析html并获取到需要的信息

1   首先得介绍如何得到淘宝的商品id号,打开淘宝,随便输入商品名称,然后在响应的源码中搜索nid,如下图:

如上图中的"nid":"44839745803",这样的数据格式,如何通过正则表达式获取当前页的所有的商品id呢?

解析的代码在源码中的From1类中的 private async void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)方法中,核心代码如下:

var html ="获取到的源码";
if (html == null || html.Length == 0)
{
     Console.WriteLine("获取网页出错");
     return;
}

//匹配的正则表达式        
string strPattern = "\"nid\":\"\\d*";
Regex reg = new Regex(strPattern, RegexOptions.IgnoreCase);
MatchCollection mc = reg.Matches(html);
if (mc.Count == 0)
{
      Console.WriteLine("获取不到数据");
}

foreach (Match m in mc)
{
  string value = m.Value;
  //接着把"nid":"使用空字符串替换就得到商品的id号了
  value = value.Replace("\"nid\":\"", "");
  Console.WriteLine(value);

}

2  获取到商品id号后,需要使用第三方解析平台获取价格信息,请求地址:

历史价格查询详情,id后面的是刚才获取的商品id号,把这个链接直接复制到浏览器并访问,得到的结果如下图:

但通过分析,价格的信息并不在html源码中,而是需要分三步

2.1 从请求的html源码中获取到checkCode的id号(请求该html源码不需要ip代理),如下图:

如何通过正则表达式获取checkCodeId呢?"checkCodeId"  value="全配,后面的使用\w*通配,加上转义,完整的正则表达式为:     "\"checkCodeId\" value=\"\\w*"   ,最后把多余的部分使用空字符串替换即可

2.2 获取到checkCodeId后,通过访问http://www.tool168.cn/dm/ptinfo.php获取code,如下图:

该文件的请求访问为POST,同时带有表单数据,如下图:

获取该html源码代码在源码中的TaoBaoOperation类中,如下:

与前面介绍的方法GetHtml唯一不同的是,这个方法不使用ip代理

  /// <summary>
        /// 获取网页源码,不使用代理
        /// </summary>
        /// <param name="url"></param>
        /// <param name="Method"></param>
        /// <param name="formData"></param>
        /// <returns></returns>
        public string GetHtmlWithOutProxy(string url, string Method, Dictionary<string, string> formData)
        {

            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //加上这一句
            Uri uri = new Uri(url);
            HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(uri);
            myReq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36";
            myReq.Accept = "*/*";
            myReq.KeepAlive = false;
            myReq.AllowAutoRedirect = true;
            myReq.Headers.Add("Accept-Language", "zh-CN,zh;q=0.9");

            myReq.ContentType = "application/x-www-form-urlencoded;charset=utf-8";


            myReq.Method = Method;
     
            //添加Form  Data
            if (formData != null && formData.Count > 0)
            {
                string formDataParam = "";
                int index = 0;
                foreach (var item in formData)
                {
                    if (index == 0)
                    {
                        formDataParam += item.Key + "=" + item.Value;
                        index++;
                    }
                    else
                    {
                        formDataParam += "&" + item.Key + "=" + item.Value;

                    }
                }


                myReq.AllowWriteStreamBuffering = true;
                byte[] buffer = Encoding.UTF8.GetBytes(formDataParam);
                myReq.ContentLength = buffer.Length;
                using (Stream requestStream = myReq.GetRequestStream())
                {

                    requestStream.Write(buffer, 0, buffer.Length);
                    requestStream.Flush();
                }
            }



            HttpWebResponse result = (HttpWebResponse)myReq.GetResponse();
            Stream receviceStream = result.GetResponseStream();
            StreamReader readerOfStream = new StreamReader(receviceStream, System.Text.Encoding.GetEncoding("utf-8"));
            string strHTML = readerOfStream.ReadToEnd();
            readerOfStream.Close();
            receviceStream.Close();
            result.Close();
            return strHTML;
        }

调用如下:

 //获取商品的CodeId
 string checkCodeId="c014ceadcf3bcc8ac922f0e8b13c1b5b";
 string shopId="554415401017";
 string con = "https://item.taobao.com/item.htm?id=" + shopId;
 string codeIdUrl = "http://www.tool168.cn/dm/ptinfo.php";
 string CodeId = GetCodeId(codeIdUrl, checkCodeId, con);


 /// <summary>
        /// 获取CodeId
        /// </summary>
        /// <param name="url"></param>
        /// <param name="checkCodeId"></param>
        /// <param name="con"></param>
        /// <returns></returns>
        private string GetCodeId(string url,string checkCodeId,string con)
        {
            Dictionary<string, string> formData = new Dictionary<string, string>();
            formData.Add("checkCode", checkCodeId);
            formData.Add("con", con);
            string codeId = "";
            string html = GetHtmlWithOutProxy(url, "POST", formData);


            string strPattern = "{\"code\":\"\\w*";
            Regex reg = new Regex(strPattern, RegexOptions.IgnoreCase);
            MatchCollection mc = reg.Matches(html);
           
            foreach (Match m in mc)
            {
                codeId = m.Value;
                codeId = codeId.Replace("{\"code\":\"", "");
                Console.WriteLine("codeId:"+codeId);
            }

           
            return codeId;
        }

2.3  获取code的id号后,就可以通过访问链接http://www.tool168.cn/dm/history.php?code=0f72c0c84e6f722de6fb57f9feb3691e26545bc2991ffc290ed35271bb855499c9da68f2257e9a908086de963a5ea291dfb568333e84958e获取商品的价格了(获取该html源码需要ip代理),返回的数据格式如下图:

如何通过正则表达式获取到每天的价格呢?使用到了特殊的技巧,先拿一个数据来分析:

项目运行的必备条件:

1  需要去淘宝购买ip代理,两块钱即可,购买链接:https://item.taobao.com/item.htm?spm=a1z09.2.0.0.1ee32e8dA9OdA6&id=570636814039&_u=62bg4snuf5b8

选择购买3个动态ip即可(2块钱),然后在TaoBaoOperation类输入购买到的链接,如下图:

返回的数据格式类似:

47.84.102.137:1245

23.23.45.139:1356

234.234.134.4:1567

2  在TaoBaoOperation类中输入淘宝账号和淘宝登录密码,如下图:

 好了,本文到此结束,如果本文对你有帮助,资助2毛钱作为鼓励呗,穷逼一个,就当筹个网费吧

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
### 回答1: WinForms CefSharp 113.1.40 是一个基于Chromium的.NET框架,用于嵌入一个自定义浏览器控件到Windows应用程序中。如果你想要支持视频播放功能,你需要进行一些额外的工作。 首先,你需要添加一个名为libcef.dll的动态链接库文件,该文件是CefSharp的核心组件之一,它提供了与Chromium进行交互的功能。你可以通过从CefSharp中文官方GitHub仓库中下载合适版本的CefSharp包来获取该文件。 一旦你有了libcef.dll文件,你需要将它复制到你的项目的输出目录中,或将其放置在你的应用程序的可执行文件所在的同一目录下。这是为了确保系统能够找到这个文件。 接下来,你需要在你的WinForms项目中引用CefSharp类库。你可以通过使用NuGet包管理器来添加CefSharp.WinForms和CefSharp.Common的引用。 一旦你完成了引用,你需要在你的WinForms的代码中创建一个CefSharp控件,并在需要显示浏览器的地方将其添加到你的窗体中。你可以使用类似下面的代码来完成: ``` using CefSharp; using CefSharp.WinForms; public class MyBrowserForm : Form { private ChromiumWebBrowser browser; public MyBrowserForm() { browser = new ChromiumWebBrowser("https://www.example.com"); Controls.Add(browser); } } ``` 以上代码将创建一个带有浏览器控件的窗体,并显示指定的URL。 至此,你已经成功创建了一个基本的自定义浏览器控件,通过CefSharp可以在你的WinForms应用程序中显示网页。如果你要支持视频播放功能,你可以在页面中嵌入HTML5的video标签或使用Flash等其他技术来实现。然后,CefSharp将能够解析并呈现这些视频。 综上所述,通过使用WinForms CefSharp 113.1.40,你可以创建一个自定义浏览器控件,并支持视频播放。为此,你需要添加libcef.dll文件到你的项目中,引用CefSharp类库,并在你的代码中创建和配置浏览器控件。希望这些信息对你有帮助。 ### 回答2: WinForm-CefSharp是一种用于嵌入Chromium浏览器的库,而CEFSharp 113.1.40是其特定版本。若想实现视频播放功能,可能需要自定义浏览器以支持视频播放DLL。 首先,需要添加CEFSharp.Wpf和其他相关库的引用来创建WinForm-CefSharp应用程序。然后,我们可以添加一个自定义的ChromiumWebBrowser控件到窗体,并将其设置为允许媒体播放。 CEFSharp支持通过CefSettings配置浏览器的各种选项。我们可以通过设置CefSettings的Plugins属性来允许浏览器加载插件。此属性可接受一个插件文件夹的路径作为参数,即希望支持的DLL文件所在的目录。 在加载CEFSharp之前,我们需要确保要加载的DLL文件已经添加到项目中,并设置其属性为始终复制。这样,在运行应用程序时,相关的DLL文件将被复制到输出目录。 接下来,我们需要处理CefSharp控件的LoadingStateChanged事件,并在事件处理程序中判断当前加载的URL类型。当加载的URL为媒体文件(例如视频)时,我们可以执行一些自定义操作,例如显示播放器控件、设置播放器的源文件等。 最后,我们可以使用CefSharp控件的ExecuteScriptAsync方法调用JavaScript代码来控制视频播放。通过执行一些相关的JavaScript函数,我们可以实现自定义的视频控制功能,如播放、暂停、跳转等。 总之,要实现WinForm-CefSharp应用程序的自定义浏览器支持视频播放DLL,我们需要添加CEFSharp和其他相关库的引用,设置浏览器的配置选项以支持插件加载,确保相关的DLL文件已添加到项目中并设置为始终复制,处理LoadingStateChanged事件来判断并控制加载的URL类型,以及通过执行JavaScript代码来实现自定义的视频播放功能。 ### 回答3: Winform-CefSharp是一个用于在Winform应用程序中嵌入Chromium浏览器的开源库。要实现自定义浏览器支持视频播放DLL,可以按照以下步骤操作。 首先,确保已经将CefSharp集成到你的Winform应用程序中。你需要在项目中引用CefSharp的相关dll文件,以及解决依赖关系。 接下来,创建一个自定义的CefSharp浏览器控件,您可以继承CefSharp.WinForms.ChromiumWebBrowser类并重写一些必要的方法。例如,你可以重写OnBeforeResourceLoad方法来拦截特定视频资源的加载请求。 在你的自定义控件中实现视频播放的逻辑。你可以通过调用CEF浏览器引擎 提供的相关方法来实现视频播放的支持。例如,你可以使用CefBrowserHost.GetFrame函数获取浏览器的当前帧,然后通过调用LoadUrl方法加载视频链接。 另外,你还需要添加将视频URL传递给CefSharp浏览器控件的方法。你可以在自定义的控件中添加一个方法,用于接收调用者传递的视频URL,并将其传递给CefSharp浏览器控件。 最后,在你的Winform应用程序中使用自定义的CefSharp浏览器控件。将该控件添加到你的界面中,并在需要的时候调用相关方法来加载和播放视频。 总结来说,要实现自定义浏览器支持视频播放DLL,你需要集成CefSharp到你的Winform应用程序中,创建自定义的CefSharp浏览器控件,并在其中实现视频播放的逻辑。然后,在你的应用程序中使用该自定义控件来加载和播放视频。这样就可以实现自定义浏览器支持视频播放DLL的功能。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxy2847225301

测试使用

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值