C#使用CefSharp和网页进行自动化交互

.NET兼职社区
.NET兼职社区
.NET兼职社区
这里以winfroms为例

1.先安装对应的包,我目前用的最新版本。
CefSharp.WinForms 版本126.2.70.0
2.nuget安装完成后,直接使用
2.1初始化

        public CefSharp.WinForms.ChromiumWebBrowser chromeBrowser;
        public void InitializeChromium()
        {
            CefSettings settings = new CefSettings();
            settings.Locale = "zh-CN";
            Cef.Initialize(settings);
            chromeBrowser = new ChromiumWebBrowser("https://www.sporttery.cn/jc/jsq/zqspf/");
            chromeBrowser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;
            //CefSharpSettings.WcfEnabled = true;
            // 添加你的C#类为可由JavaScript调用
            chromeBrowser.JavascriptObjectRepository.Register("bridge", new JsToCSharpBridge(), false, BindingOptions.DefaultBinder);

            // 添加事件处理器以监听页面加载结束
            chromeBrowser.FrameLoadEnd += OnBrowserFrameLoadEnd;
            //添加控件
            this.Controls.Add(chromeBrowser);
            this.chromeBrowser.Dock = DockStyle.Fill;
            chromeBrowser.KeyboardHandler = new CEFKeyBoardHander();

        }

2.2如果你需要在网页加载好后,就注入JS事件,可以写在OnBrowserFrameLoadEnd

 private  void OnBrowserFrameLoadEnd(object sender, FrameLoadEndEventArgs e)
 {
     if (e.Frame.IsMain)
     {
         // 注入JavaScript以添加点击事件
         string script = @"
             (function() {
                 var btn = document.querySelector('#detailBtn');
                 if (btn) {
                     btn.addEventListener('click', function() {
                      setTimeout(function() {
                                  var result1 = document.querySelector('#viewDetailTbl > tr:nth-child(1) > td:nth-child(2)').textContent
                                  console.log(111); 
                                  console.log(result1); 

                                  bridge.callCSharpFunction(result1);



                             }, 500); // 等待1秒
                        

                     });
                 }
             })();
         "; 
         e.Frame.ExecuteJavaScriptAsync(script);


     }
 }

这里意思是页面加载完成后,给页面中的按钮注入一个点击事件。其中ExecuteJavaScriptAsync用于注入JS,这个是没有返回值的。

2.3接下来我们看看如何注入JS到网页中,并且带返回值。

        private async void button1_Click(object sender, EventArgs e)
        {

            var js = @"
                    (() => {
                 
                      var week1 = document.querySelector('#list_1025933 > td:nth-child(1)').textContent
                      var lname1 = document.querySelector('#list_1025933 > td.lname > a').text
                      var vsTd1 = document.querySelector('#list_1025933 > td.vsTd').textContent
                      var win1 = document.querySelector('#list_1025933 > td:nth-child(6) > div.hadOdds.bLine > span:nth-child(1)').textContent
                      var week2 = document.querySelector('#list_1025934 > td:nth-child(1)').textContent
                      var lname2 = document.querySelector('#list_1025934 > td.lname > a').text
                      var vsTd2 = document.querySelector('#list_1025934 > td.vsTd').textContent
                      var flat = document.querySelector('#list_1025934 > td:nth-child(6) > div.hadOdds.bLine > span:nth-child(2)').textContent
                        var times = document.querySelector('#times').value;
                        var consume = document.querySelector('#consume').textContent;
                        var bonus = document.querySelector('#bonus').textContent;
                        return {week1,lname1,vsTd1,win1,week2,lname2,vsTd2,flat,times, consume, bonus };
                    })();
                ";

            dynamic result = await chromeBrowser.EvaluateScriptAsync(js);

            // 访问返回的JSON对象的属性

           // string result1 = result.Result.result1;
            string times = result.Result.times;
            string consume = result.Result.consume;
            string bonus = result.Result.bonus;

            // 使用返回的数据
            MessageBox.Show($"{result.Result.week1}{result.Result.lname1}{result.Result.vsTd1}{result.Result.win1}\n{result.Result.week2}{result.Result.lname2}{result.Result.vsTd2}{result.Result.flat}\n{result1}  \n倍率: {times} 投注: {consume} 理论最高奖金: {bonus}");
        }

这里就是点击winfrom中的按钮,然后注入JS,JS执行后把JS的结果返回给C#。

2.4接着我们看看如何通过JS调用C#中的函数

        public class JsToCSharpBridge
        {
            public void callCSharpFunction(string message)
            {

                // 在这里调用你自己的C#函数
                result1 = message;
            }
        }
        static string result1 = string.Empty;

首先我们要定义JS调用的方法,这里单独写一个类,然后需要在初始化的时候注入这个类

 chromeBrowser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;
            //CefSharpSettings.WcfEnabled = true;
            // 添加你的C#类为可由JavaScript调用
            chromeBrowser.JavascriptObjectRepository.Register("bridge", new JsToCSharpBridge(), false, BindingOptions.DefaultBinder);

只有注入了,才能被JS代码识别,然后调用。
bridge.callCSharpFunction(result1);这个就是调用方式。这句话在页面加载后,注入点击事件中有写到。
2.5开启调试模式

        public class CEFKeyBoardHander : IKeyboardHandler
        {
            public bool OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey)
            {
                if (type == KeyType.KeyUp && Enum.IsDefined(typeof(Keys), windowsKeyCode))
                {
                    var key = (Keys)windowsKeyCode;
                    switch (key)
                    {
                        case Keys.F12:
                            browser.ShowDevTools();
                            break;

                        case Keys.F5:

                            if (modifiers == CefEventFlags.ControlDown)
                            {
                                //MessageBox.Show("ctrl+f5");
                                browser.Reload(true); //强制忽略缓存

                            }
                            else
                            {
                                //MessageBox.Show("f5");
                                browser.Reload();
                            }
                            break;


                    }
                }
                return false;
            }

            public bool OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut)
            {
                return false;
            }
        }

初始化的时候添加:
chromeBrowser.KeyboardHandler = new CEFKeyBoardHander();这样就可以在winfrom中按F12进行调试
记得关闭窗体的时候,关掉cef引擎

       private void Form1_FormClosing(object sender, FormClosingEventArgs e)
       {
           Cef.Shutdown();
          //chromeBrowser.CloseDevTools();
       }

接着给出所有代码:

using CefSharp.WinForms;
using System;
using System.Windows.Forms;

namespace CefSharp.demo
{
    


    public partial class Form1 : Form
    {
        public class JsToCSharpBridge
        {
            public void callCSharpFunction(string message)
            {

                // 在这里调用你自己的C#函数
                result1 = message;
            }
        }
        static string result1 = string.Empty;
        public Form1()
        {
            InitializeComponent();
            InitializeChromium();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
  

        }

        public CefSharp.WinForms.ChromiumWebBrowser chromeBrowser;
        public void InitializeChromium()
        {
            CefSettings settings = new CefSettings();
            settings.Locale = "zh-CN";
            Cef.Initialize(settings);
            chromeBrowser = new ChromiumWebBrowser("https://www.sporttery.cn/jc/jsq/zqspf/");
            chromeBrowser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;
            //CefSharpSettings.WcfEnabled = true;
            // 添加你的C#类为可由JavaScript调用
            chromeBrowser.JavascriptObjectRepository.Register("bridge", new JsToCSharpBridge(), false, BindingOptions.DefaultBinder);

            // 添加事件处理器以监听页面加载结束
            chromeBrowser.FrameLoadEnd += OnBrowserFrameLoadEnd;
            //添加控件
            this.Controls.Add(chromeBrowser);
            this.chromeBrowser.Dock = DockStyle.Fill;
            chromeBrowser.KeyboardHandler = new CEFKeyBoardHander();

        }

        private  void OnBrowserFrameLoadEnd(object sender, FrameLoadEndEventArgs e)
        {
            if (e.Frame.IsMain)
            {
                // 注入JavaScript以添加点击事件
                string script = @"
                    (function() {
                        var btn = document.querySelector('#detailBtn');
                        if (btn) {
                            btn.addEventListener('click', function() {
                             setTimeout(function() {
                                         var result1 = document.querySelector('#viewDetailTbl > tr:nth-child(1) > td:nth-child(2)').textContent
                                         console.log(111); 
                                         console.log(result1); 

                                         bridge.callCSharpFunction(result1);



                                    }, 500); // 等待1秒
                               

                            });
                        }
                    })();
                "; 
                e.Frame.ExecuteJavaScriptAsync(script);


            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Cef.Shutdown();
           //chromeBrowser.CloseDevTools();
        }

        public class CEFKeyBoardHander : IKeyboardHandler
        {
            public bool OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey)
            {
                if (type == KeyType.KeyUp && Enum.IsDefined(typeof(Keys), windowsKeyCode))
                {
                    var key = (Keys)windowsKeyCode;
                    switch (key)
                    {
                        case Keys.F12:
                            browser.ShowDevTools();
                            break;

                        case Keys.F5:

                            if (modifiers == CefEventFlags.ControlDown)
                            {
                                //MessageBox.Show("ctrl+f5");
                                browser.Reload(true); //强制忽略缓存

                            }
                            else
                            {
                                //MessageBox.Show("f5");
                                browser.Reload();
                            }
                            break;


                    }
                }
                return false;
            }

            public bool OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut)
            {
                return false;
            }
        }

        private async void button1_Click(object sender, EventArgs e)
        {

            var js = @"
                    (() => {
                 
                      var week1 = document.querySelector('#list_1025933 > td:nth-child(1)').textContent
                      var lname1 = document.querySelector('#list_1025933 > td.lname > a').text
                      var vsTd1 = document.querySelector('#list_1025933 > td.vsTd').textContent
                      var win1 = document.querySelector('#list_1025933 > td:nth-child(6) > div.hadOdds.bLine > span:nth-child(1)').textContent
                      var week2 = document.querySelector('#list_1025934 > td:nth-child(1)').textContent
                      var lname2 = document.querySelector('#list_1025934 > td.lname > a').text
                      var vsTd2 = document.querySelector('#list_1025934 > td.vsTd').textContent
                      var flat = document.querySelector('#list_1025934 > td:nth-child(6) > div.hadOdds.bLine > span:nth-child(2)').textContent
                        var times = document.querySelector('#times').value;
                        var consume = document.querySelector('#consume').textContent;
                        var bonus = document.querySelector('#bonus').textContent;
                        return {week1,lname1,vsTd1,win1,week2,lname2,vsTd2,flat,times, consume, bonus };
                    })();
                ";

            dynamic result = await chromeBrowser.EvaluateScriptAsync(js);

            // 访问返回的JSON对象的属性

           // string result1 = result.Result.result1;
            string times = result.Result.times;
            string consume = result.Result.consume;
            string bonus = result.Result.bonus;

            // 使用返回的数据
            MessageBox.Show($"{result.Result.week1}{result.Result.lname1}{result.Result.vsTd1}{result.Result.win1}\n{result.Result.week2}{result.Result.lname2}{result.Result.vsTd2}{result.Result.flat}\n{result1}  \n倍率: {times} 投注: {consume} 理论最高奖金: {bonus}");
        }
    }
}

实现C语言可以指两种不同的情况,一种是指实现C语言的编译器,另一种是指用C语言编写的软件或程序。 如果是指实现C语言的编译器,首先需要了解编译器的基本原理和C语言的语法规则。然后可以选择一种合适的编程语言(例如C++)来编写编译器的代码。编写编译器的过程中,需要逐步实现词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等多个阶段。其中,词法分析负责将源代码分解成一个个的词法单元,语法分析负责根据语法规则构建抽象语法树,语义分析负责对抽象语法树进行类型检查和语义分析,中间代码生成负责将抽象语法树转化为中间代码,代码优化负责对中间代码进行优化,目标代码生成负责将中间代码转化为目标机器代码。 如果是指用C语言编写的软件或程序,首先需要明确需求,然后设计软件的结构和功能模块。根据需求和设计,可以使用C语言的语法和函数库来编写软件的代码。在编写代码的过程中,需要注意C语言的语法规则和编码规范,确保代码的可读性和可维护性。同时,还需要进行测试和调试,确保软件的正确性和稳定性。 总而言之,实现C语言需要具备相应的知识和技能,并按照编译器或软件开发的流程进行相应的步骤。在实现的过程中,需要不断学习和积累经验,同时注意代码的质量和性能。实现C语言可以帮助我们更好地理解和应用C语言,同时也可以提升我们的编程技能和能力。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值