最近在做使用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; } }
评论区