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