最近在做使用CefSharp 登录各个平台自动发送文章、新闻等因此有如下封装类:
public static class DomHelper
{
/// <summary>
/// 获取元素所在位置
/// </summary>
/// <param name="browser"></param>
/// <param name="tag"></param>
/// <returns></returns>
public static BoundingClientRect GetBoundingClientRectAsync(this IBrowser browser, string tag)
{
string script = "(function(){";
script += "var doc = document.querySelector('" + tag + "');";
script += @"if(doc!=null){
let bntRect = doc.getBoundingClientRect();
let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom });
return result;
};
return null;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait();//等待脚本执行完
var response = result.Result;
if (response.Success && response.Result == null) return null;
if (response.Result == null) return null;
BoundingClientRect? bc = JsonSerializer.Deserialize<BoundingClientRect>(response.Result.ToString());
return bc;
}
/// <summary>
/// 通过xpath 语法获取坐标
/// </summary>
/// <param name="browser"></param>
/// <param name="tag"></param>
/// <returns></returns>
public static BoundingClientRect GetXPathBoundingClientRect(this IBrowser browser, string tag)
{
string script = "(function(){";
script += "var doc= document.evaluate(\"" + tag + "\",document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;";
script += @"if(doc != null){
let bntRect = doc.getBoundingClientRect();
let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom });
return result;
};
return null;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait();//等待脚本执行完
if (result == null) return null;
var response = result.Result;
if (response.Success && response.Result == null) return null;
BoundingClientRect? bc = JsonSerializer.Deserialize<BoundingClientRect>(response.Result.ToString());
return bc;
}
/// <summary>
/// 模拟点击指定选择符DOM元素
/// </summary>
/// <param name="selector">jQuery选择符</param>
public static void ClickElement(this IBrowser browser, double? left, double? top, bool isFocusEvent = false)
{
var host = browser.GetHost();
var x = Convert.ToInt32(left) + 5;
var y = Convert.ToInt32(top) + 5;
host.SendMouseMoveEvent(x, y, false, CefEventFlags.None);//移动鼠标
Thread.Sleep(50);
host.SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.None);//按下鼠标左键
Thread.Sleep(50);
host.SendFocusEvent(isFocusEvent);
Thread.Sleep(50);
host.SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);//松开鼠标左键
}
/// <summary>
/// 按下回车事件
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public static void HitEnter(this IBrowser browser, int x, int y)
{
KeyEvent k = new KeyEvent
{
WindowsKeyCode = 0x0D, // Enter
FocusOnEditableField = true,
IsSystemKey = false,
Type = KeyEventType.KeyDown
};
browser.GetHost().SendKeyEvent(k);
//browser.GetHost().SendFocusEvent();
Thread.Sleep(100);
k = new KeyEvent
{
WindowsKeyCode = 0x0D, // Enter
FocusOnEditableField = true,
IsSystemKey = false,
Type = KeyEventType.KeyUp
};
browser.GetHost().SendKeyEvent(k);
Thread.Sleep(100);
}
/// <summary>
/// 输入内容
/// </summary>
/// <param name="browser"></param>
/// <param name="inputString"></param>
public static void Input(this IBrowser browser, string inputString)
{
//var inputString = "CefSharp Was Here!";
var host = browser.GetHost();
foreach (var c in inputString)
{
host.SendKeyEvent(new KeyEvent { WindowsKeyCode = c, Type = KeyEventType.Char });
}
}
/// <summary>
/// 输入帐号
/// </summary>
/// <param name="browser">当前浏览器</param>
/// <param name="userName">用户名</param>
/// <param name="x">x坐标</param>
/// <param name="y">y坐标</param>
public static void InputUser(this IBrowser browser, string userName, double? x, double? y)
{
browser.ClickElement(x, y, true);
Thread.Sleep(100);
browser.Input(userName);//输入帐号
Thread.Sleep(300);
}
/// <summary>
/// 输入密码
/// </summary>
/// <param name="browser"></param>
/// <param name="pass"></param>
/// <param name="x"></param>
/// <param name="y"></param>
public static void InputPass(this IBrowser browser, string pass, double? x, double? y)
{
browser.ClickElement(x, y, true);
Thread.Sleep(100);
browser.Input(pass);//输入帐号
Thread.Sleep(300);
}
/// <summary>
/// 判断标签是否存在
/// </summary>
/// <param name="browser"></param>
/// <param name="tag"></param>
public static bool IsQuerySelector(this IBrowser browser, string tag)
{
string script = "(function(){";
script += "var doc = document.querySelector('" + tag + "');";
script += @"if(doc==null) return null;
let bntRect = doc.getBoundingClientRect();
let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom });
return result;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait();//等待脚本执行完
var response = result.Result;
if (response.Success && response.Result == null) return false;
if (response.Result == null) return false;
return true;
}
/// <summary>
/// 通过xpath 语法判断元素是否存在
/// </summary>
/// <param name="browser"></param>
/// <param name="tag"></param>
/// <returns></returns>
public static bool IsXPathQuerySelector(this IBrowser browser, string tag)
{
string script = "(function(){";
script += "var doc= document.evaluate(\"" + tag + "\",document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;";
script += @"if(doc == null) return null;
let bntRect = doc.getBoundingClientRect();
let result =JSON.stringify({ x: bntRect.left, y: bntRect.top,r:bntRect.right,b:bntRect.bottom });
return result;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait();//等待脚本执行完
if (result == null) return false;
var response = result.Result;
if (response.Success && response.Result == null) return false;
return true;
}
/// <summary>
/// 发送鼠标滚轮事件
/// </summary>
/// <param name="browser"></param>
/// <param name="left"></param>
/// <param name="top"></param>
public static void SendMouseWheel(this IBrowser browser, double? left, double? top)
{
var host = browser.GetHost();
var x = Convert.ToInt32(left) + 5;
var y = Convert.ToInt32(top) + 5;
host.SendMouseWheelEvent(Convert.ToInt32(0), Convert.ToInt32(top), x, y, CefEventFlags.None);
Thread.Sleep(50);
host.SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.None);//按下鼠标左键
Thread.Sleep(50);
Thread.Sleep(50);
host.SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);//松开鼠标左键
}
/// <summary>
/// 滚动到指定元素上
/// </summary>
public static bool ScrollIntoView(this IBrowser browser, string tag)
{
string script = "(function(){";
script += "var doc= document.evaluate(\"" + tag + "\",document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;";
script += @"if(doc != null){doc.scrollIntoView({block: 'center',behavior: 'smooth'}); return true};
return false;
})()";
Task<JavascriptResponse> result = browser.EvaluateScriptAsync(script);
result.Wait();//等待脚本执行完
if (result == null) return false;
var response = result.Result;
if (response.Success && response.Result == null) return false;
var bo = (bool)response.Result;
return bo;
}
}BoundingClientRect类:
[Serializable]
public class BoundingClientRect
{
public double? x { get; set; }
public double? y { get; set; }
public double? r { get; set; }
public double? b { get; set; }
}
评论区