C#使用CefSharp和网页进行自动化交互的示例代码
作者:爱吃奶酪的松鼠丶
CefSharp 是一个用 C# 编写的开源库,它封装了 Google Chrome 浏览器的 Chromium 内核,CefSharp 允许开发者在其应用程序中嵌入浏览器功能,从而能够展示网页内容、执行JavaScript代码,本文给大家介绍了C#使用CefSharp和网页进行自动化交互,需要的朋友可以参考下
这里以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#使用CefSharp和网页进行自动化交互的示例代码的文章就介绍到这了,更多相关C# CefSharp和网页自动化交互内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!