C#使用CefSharp和網(wǎng)頁進(jìn)行自動(dòng)化交互的示例代碼
這里以winfroms為例
1.先安裝對(duì)應(yīng)的包,我目前用的最新版本。
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調(diào)用
chromeBrowser.JavascriptObjectRepository.Register("bridge", new JsToCSharpBridge(), false, BindingOptions.DefaultBinder);
// 添加事件處理器以監(jiān)聽頁面加載結(jié)束
chromeBrowser.FrameLoadEnd += OnBrowserFrameLoadEnd;
//添加控件
this.Controls.Add(chromeBrowser);
this.chromeBrowser.Dock = DockStyle.Fill;
chromeBrowser.KeyboardHandler = new CEFKeyBoardHander();
}
2.2、如果你需要在網(wǎng)頁加載好后,就注入JS事件,可以寫在OnBrowserFrameLoadEnd中
private void OnBrowserFrameLoadEnd(object sender, FrameLoadEndEventArgs e)
{
if (e.Frame.IsMain)
{
// 注入JavaScript以添加點(diǎn)擊事件
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);
}
}
這里意思是頁面加載完成后,給頁面中的按鈕注入一個(gè)點(diǎn)擊事件。其中ExecuteJavaScriptAsync用于注入JS,這個(gè)是沒有返回值的。
2.3、接下來我們看看如何注入JS到網(wǎng)頁中,并且?guī)Х祷刂怠?/p>
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對(duì)象的屬性
// string result1 = result.Result.result1;
string times = result.Result.times;
string consume = result.Result.consume;
string bonus = result.Result.bonus;
// 使用返回的數(shù)據(jù)
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} 理論最高獎(jiǎng)金: {bonus}");
}
這里就是點(diǎn)擊winfrom中的按鈕,然后注入JS,JS執(zhí)行后把JS的結(jié)果返回給C#。
2.4、接著我們看看如何通過JS調(diào)用C#中的函數(shù)
public class JsToCSharpBridge
{
public void callCSharpFunction(string message)
{
// 在這里調(diào)用你自己的C#函數(shù)
result1 = message;
}
}
static string result1 = string.Empty;
首先我們要定義JS調(diào)用的方法,這里單獨(dú)寫一個(gè)類,然后需要在初始化的時(shí)候注入這個(gè)類
chromeBrowser.JavascriptObjectRepository.Settings.LegacyBindingEnabled = true;
//CefSharpSettings.WcfEnabled = true;
// 添加你的C#類為可由JavaScript調(diào)用
chromeBrowser.JavascriptObjectRepository.Register("bridge", new JsToCSharpBridge(), false, BindingOptions.DefaultBinder);
只有注入了,才能被JS代碼識(shí)別,然后調(diào)用。bridge.callCSharpFunction(result1);這個(gè)就是調(diào)用方式。這句話在頁面加載后,注入點(diǎn)擊事件中有寫到。
2.5、開啟調(diào)試模式
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); //強(qiáng)制忽略緩存
}
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;
}
}
初始化的時(shí)候添加:chromeBrowser.KeyboardHandler = new CEFKeyBoardHander();這樣就可以在winfrom中按F12進(jìn)行調(diào)試
記得關(guān)閉窗體的時(shí)候,關(guān)掉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)
{
// 在這里調(diào)用你自己的C#函數(shù)
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調(diào)用
chromeBrowser.JavascriptObjectRepository.Register("bridge", new JsToCSharpBridge(), false, BindingOptions.DefaultBinder);
// 添加事件處理器以監(jiān)聽頁面加載結(jié)束
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以添加點(diǎn)擊事件
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); //強(qiáng)制忽略緩存
}
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對(duì)象的屬性
// string result1 = result.Result.result1;
string times = result.Result.times;
string consume = result.Result.consume;
string bonus = result.Result.bonus;
// 使用返回的數(shù)據(jù)
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} 理論最高獎(jiǎng)金: {bonus}");
}
}
}
到此這篇關(guān)于C#使用CefSharp和網(wǎng)頁進(jìn)行自動(dòng)化交互的示例代碼的文章就介紹到這了,更多相關(guān)C# CefSharp和網(wǎng)頁自動(dòng)化交互內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#中Monitor對(duì)象與Lock關(guān)鍵字的區(qū)別分析
這篇文章主要介紹了C#中Monitor對(duì)象與Lock關(guān)鍵字的區(qū)別,需要的朋友可以參考下2013-06-06
C#小知識(shí)之有趣的類型靜態(tài)構(gòu)造器
這篇文章主要介紹了C#小知識(shí)之有趣的類型靜態(tài)構(gòu)造器,本文直接給分實(shí)例代碼,然后分析了C#中的這一個(gè)有趣的現(xiàn)象,需要的朋友可以參考下2015-04-04
給c#添加SetTimeout和SetInterval函數(shù)
Javascript中的SetTimeout和SetInterval函數(shù)很方便,把他們移植到c#中來。2008-03-03
C#實(shí)現(xiàn)的json序列化和反序列化代碼實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)的json序列化和反序列化代碼實(shí)例,本文講解了兩種實(shí)現(xiàn)方法,并直接給出代碼示例,需要的朋友可以參考下2015-06-06
WPF如何利用附加屬性修改ShowGridLines效果詳解
這篇文章主要給大家介紹了關(guān)于WPF如何利用附加屬性修改ShowGridLines效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2018-04-04
C# 常用協(xié)議實(shí)現(xiàn)模版及FixedSizeReceiveFilter示例(SuperSocket入門)
本文主要介紹了常用協(xié)議實(shí)現(xiàn)模版及FixedSizeReceiveFilter示例。具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-01-01
算法證明每一位都相同十進(jìn)制數(shù)不是完全平方數(shù)
這篇文章主要為大家介紹了算法證明每一位都相同十進(jìn)制數(shù)不是完全平方數(shù)的過程論述,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05

