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}");
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/776652.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设计模式探索:代理模式

1. 什么是代理模式 定义 代理模式是一种结构型设计模式,通过为其他对象提供一种代理以控制对这个对象的访问。代理对象在客户端和实际对象之间起到中介作用,可以在不改变真实对象的情况下增强或控制对真实对象的访问。 目的 代理模式的主要目的是隐…

着急,为啥AI叫好不叫座啊?

关注卢松松,会经常给你分享一些我的经验和观点。 李彦宏在2024世界人工智能大会上说: 没有应用,光有基础模型,不管是开源还是闭源都一文不值,所以我从去年下半年开始讲,大家不要卷模型了,要去…

MySQL---事务管理

1.关于事务 理解和学习事务,不能只站在程序猿的角度来理解事务,而是要站在使用者(用户)的角度来理解事务。 比如支付宝转账,A转了B100块前,在程序猿的角度来看,是两条update操作,A …

PCDN技术如何提高内容分发效率?(贰)

PCDN技术通过以下方式提高内容分发效率: 1.利用用户设备作为分发节点:与传统的 CDN技术主要依赖中心化服务器不同, PCDN技术利用用户的设备作为内容分发的节点。当用户下载内容时,他们的设备也会成为内容分发的一部分,将已下载的内容传递给其…

项目部署_持续集成_Jenkins

1 今日内容介绍 1.1 什么是持续集成 持续集成( Continuous integration , 简称 CI )指的是,频繁地(一天多次)将代码集成到主干 持续集成的组成要素 一个自动构建过程, 从检出代码、 编译构建…

树状数组实现 查找逆序对

题意&#xff1a; 输入一个整数n。 接下来输入一行n个整数 。 1< < n ,且每个数字只会出现一次 题解&#xff1a; 按每个数字的大小存入树状数组 #include<bits/stdc.h> using namespace std; #define ll long long const int N10000; int arr[N]; ll a[N];…

Java中关于构造代码块和静态代码块的解析

构造代码块 特点&#xff1a;优先于构造方法执行,每new一次,就会执行一次 public class Person {public Person(){System.out.println("我是无参构造方法");}{System.out.println("我是构造代码块"); //构造代码块} }public class Test {public stati…

golang与以太坊交互

文章目录 golang与以太坊交互什么是go-ethereum与节点交互前的准备使用golang与以太坊区块链交互查询账户的余额使用golang生成以太坊账户使用golang生成以太坊钱包使用golang在账户之间转移eth安装使用solc和abigen生成bin和abi文件生成go文件使用golang在测试网上部署智能合约…

GD32MCU如何实现掉电数据保存?

大家在GD32 MCU应用时&#xff0c;是否会碰到以下应用需求&#xff1a;希望在MCU掉电时保存一定的数据或标志&#xff0c;用以记录一些关键的数据。 以GD32E103为例&#xff0c;数据的存储介质可以选择内部Flash或者备份数据寄存器。 如下图所示&#xff0c;片内Flash具有10年…

【综合能源】计及碳捕集电厂低碳特性及需求响应的综合能源系统多时间尺度调度模型

目录 1 主要内容 2 部分程序 3 实现效果 4 下载链接 1 主要内容 本程序是对《计及碳捕集电厂低碳特性的含风电电力系统源-荷多时间尺度调度方法》方法复现&#xff0c;非完全复现&#xff0c;只做了日前日内部分&#xff0c;并在上述基础上改进升级为电热综合电源微网系统&…

力扣习题--找不同

目录 前言 题目和解析 1、找不同 2、 思路和解析 总结 前言 本系列的所有习题均来自于力扣网站LeetBook - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 题目和解析 1、找不同 给定两个字符串 s 和 t &#xff0c;它们只包含小写字母。 字符串 t…

智能光伏开发都能用到什么软件和工具?

随着全球对可再生能源的日益重视和光伏技术的快速发展&#xff0c;智能光伏开发已成为推动能源转型的重要力量。在光伏项目的全生命周期中&#xff0c;从设计、建设到运营管理&#xff0c;各种软件和工具的应用发挥着至关重要的作用。 一、光伏系统设计软件 1、PVsyst PVsyst…

Python创建MySQL数据库

一、使用Docker部署本地MySQL数据库 docker run --restartalways -p 3307:3306 --name mysql -e MYSOL_ROOT_PASSWORDlms123456 -d mysql:8.0.25 参数解析: 用户名:root 密码:lms123456 端口:3307 二、在Pycharm开发工具中配置连接MySQL数据库 三、安装zdppy_mysql pip inst…

【LabVIEW学习篇 - 2】:LabVIEW的编程特点

文章目录 LabVIEW的编程特点图形编程天然并行运行基于数据流运行 LabVIEW的编程特点 图形编程 LabVIEW使用图形化的图形化编程语言&#xff08;G语言&#xff09;&#xff0c;用户通过在程序框图中拖放和连接各种节点&#xff08;Nodes&#xff09;来编写程序。每个节点代表一…

tobias实现支付宝支付

tobias是一个为支付宝支付SDK做的Flutter插件。 如何使用 你需要在pubspec.yaml中配置url_scheme。url_scheme是一个独特的字符串&#xff0c;用来重新启动你的app&#xff0c;但是请注意字符串“_”是不合法的。 在iOS端&#xff0c;你还需要配置并传入一个universal link。…

动手学深度学习(Pytorch版)代码实践 -循环神经网络-53语言模型和数据集

53语言模型和数据集 1.自然语言统计 引入库和读取数据&#xff1a; import random import torch from d2l import torch as d2l import liliPytorch as lp import numpy as np import matplotlib.pyplot as plttokens lp.tokenize(lp.read_time_machine())一元语法&#xf…

利用Redis bitmap 实现签到案例

数据库实现 设计签到功能对应的数据库表 CREATE TABLE sign_record (id bigint NOT NULL AUTO_INCREMENT COMMENT 主键,user_id bigint NOT NULL COMMENT 用户id,year year NOT NULL COMMENT 签到年份,month tinyint NOT NULL COMMENT 签到月份,date date NOT NULL COMMENT 签…

物联网行业等保有什么要求

中国网络安全等级保护制度&#xff08;简称“等保”&#xff09;对物联网行业有特定的要求&#xff0c;以确保物联网系统的安全性。等保2.0在原有安全通用要求的基础上&#xff0c;增加了针对新技术如云计算、物联网、移动互联网等的扩展要求。以下是一些关键的物联网安全扩展要…

C语言编译和编译预处理

编译预处理 • 编译是指把高级语言编写的源程序翻译成计算机可识别的二进制程序&#xff08;目标程序&#xff09;的过程&#xff0c;它由编译程序完成。 • 编译预处理是指在编译之前所作的处理工作&#xff0c;它由编译预处理程序完成 在对一个源程序进行编译时&#xff0c;…

小红书矩阵系统源码:赋能内容创作与电商营销的创新工具

在内容驱动的电商时代&#xff0c;小红书凭借其独特的社区氛围和用户基础&#xff0c;成为品牌营销和个人创作者不可忽视的平台。小红书矩阵系统源码&#xff0c;作为支撑这一平台的核心技术&#xff0c;提供了一系列的功能和优势&#xff0c;助力用户在小红书生态中实现更高效…