/// <summary> /// 组装节点对象 /// </summary> /// <param name="browser"></param> /// <param name="tag"></param> /// <param name="document"></param> /// <returns></returns> public static string AssembleIframeDocument(this IBrowser browser, string tag, string document = "document") { string script = "document.evaluate(\"" + tag.Replace("\"", "'") + "\"," + document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue.contentWindow.document"; return script; } /// <summary> /// 组装节点对象 /// </summary> /// <param name="browser"></param> /// <param name="tag"></param> /// <param name="document"></param> /// <returns></returns> public static string AssembleDocument(this IBrowser browser, string tag, string document = "document") { string script = "document.evaluate(\"" + tag.Replace("\"", "'") + "\"," + document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue"; return script; } /// <summary> /// 获取元素所在位置 /// </summary> /// <param name="browser">浏览器对象</param> /// <param name="tag">标签(NodeName)</param> /// <param name="document">html文档(xpath才技持)</param> /// <returns></returns> public static BoundingClientRect GetBoundingClientRect(this IBrowser browser, string tag, string document = "document") { var isXPath = Regex.IsMatch(tag, "(^//.*)"); if (isXPath) { string script = "(function(){"; script += "var doc= document.evaluate(\"" + tag.Replace("\"", "'") + "\"," + 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();//等待脚本执行完 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; } else { string script = "(function(){"; script += "var doc = document.querySelector(\"" + tag.Replace("\"", "'") + "\");"; 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> /// 通过ini指定值获取坐标 /// </summary> /// <param name="browser"></param> /// <param name="key">ini配置文件<k,v> k</param> /// <param name="path">ini配置文件路径</param> /// <returns></returns> public static BoundingClientRect GetPosition(this IBrowser browser, string key, string path, string document = "document") { string tagText = INIHelper.Read("tag", key, path);//@"input[name=pass]"; tagText = string.IsNullOrWhiteSpace(tagText) ? INIHelper.Read("tagXPath", key, path) : tagText; var isLabel = browser.CheckLabel(tagText, document); if (!isLabel) return null; var bc = browser.GetBoundingClientRect(tagText, document);//获取登录按钮位置 if (bc == null) return null; 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="browser"></param> /// <param name="left"></param> /// <param name="top"></param> public static void SelectAllKeyEvent(this IBrowser browser) { KeyEvent k = new KeyEvent { WindowsKeyCode = 0x41, // A = 0x41, FocusOnEditableField = true, Modifiers = CefEventFlags.ControlDown, Type = KeyEventType.KeyDown, IsSystemKey = false }; browser.GetHost().SendKeyEvent(k); Thread.Sleep(100); k = new KeyEvent { WindowsKeyCode = 0x41, // A = 0x41, FocusOnEditableField = true, Modifiers = CefEventFlags.ControlDown, Type = KeyEventType.KeyUp, IsSystemKey = false }; browser.GetHost().SendKeyEvent(k); Thread.Sleep(100); } /// <summary> /// 向前删除 /// </summary> /// <param name="browser"></param> public static void BackSpaceKeyEvent(this IBrowser browser) { KeyEvent k = new KeyEvent { WindowsKeyCode = 0x08, // Back = 0x08, FocusOnEditableField = true, Modifiers = CefEventFlags.None, IsSystemKey = false, Type = KeyEventType.KeyDown }; browser.GetHost().SendKeyEvent(k); Thread.Sleep(100); k = new KeyEvent { WindowsKeyCode = 0x08, // Back = 0x08, FocusOnEditableField = true, Modifiers = CefEventFlags.None, IsSystemKey = false, Type = KeyEventType.KeyUp }; browser.GetHost().SendKeyEvent(k); Thread.Sleep(100); } /// <summary> /// 按下回车事件 /// </summary> /// <param name="x"></param> /// <param name="y"></param> public static void HitEnterKeyEvent(this IBrowser browser, double? left, double? top) { 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">标签(NodeName)</param> /// <param name="document">html文档(xpath才技持)</param> /// <returns></returns> public static bool IsQuerySelector(this IBrowser browser, string tag, string document = "document") { var isXPath = Regex.IsMatch(tag, "(^//.*)"); if (isXPath) { string script = "(function(){"; script += "var doc= document.evaluate(\"" + tag.Replace("\"", "'") + "\","+ document + ",null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;"; script += @"if(doc == null) return null; let result =JSON.stringify({ data:true }); 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; } else { string script = "(function(){"; script += "var doc = document.querySelector(\"" + tag.Replace("\"", "'") + "\");"; script += @"if(doc==null) return null; let result =JSON.stringify({ data:true }); 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> /// 发送鼠标滚轮事件 /// </summary> /// <param name="browser">浏览器对象</param> /// <param name="left">x</param> /// <param name="top">y</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> /// <param name="browser">浏览器对象</param> /// <param name="tag">标签(NodeName)</param> /// <param name="document">html文档(xpath才技持)</param> /// <returns></returns> private static bool ScrollIntoView(this IBrowser browser, string tag, string document = "document") { var isXPath = Regex.IsMatch(tag, "(^//.*)"); if (isXPath) { 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();//等待脚本执行完 var response = result.Result; if (response.Success && response.Result == null) return false; if (response.Result == null) return false; var bo = (bool)response.Result; return bo; } else { string script = "(function(){"; script += "var doc = document.querySelector(\"" + tag.Replace("\"", "'") + "\");"; script += @"if(doc != null){doc.scrollIntoView({block: 'center',behavior: 'smooth'}); return true}; return false; })()"; 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; var bo = (bool)response.Result; return bo; } } /// <summary> /// 滚动到指定元素上 /// </summary> /// <param name="browser"></param> /// <param name="key">ini配置文件<k,v> k</param> /// <param name="path">ini配置文件路径</param> /// <param name="document"></param> /// <returns></returns> public static bool ScrollIntoView(this IBrowser browser, string key, string path, string document = "document") { string tagText = INIHelper.Read("tag", key, path); tagText = string.IsNullOrWhiteSpace(tagText) ? INIHelper.Read("tagXPath", key, path) : tagText; var isLabel = browser.CheckLabel(tagText, document); if (!isLabel) return false; var bc = browser.ScrollIntoView(tagText, document); if (bc == false) return false; return bc; } /// <summary> /// 检查标签是否存在 /// </summary> /// <param name="browser">浏览器对象</param> /// <param name="tag">标签(NodeName)</param> /// <param name="document">html文档(xpath才技持)</param> /// <returns></returns> public static bool CheckLabel(this IBrowser browser, string tag, string document = "document") { var isXPath = Regex.IsMatch(tag, "(^//.*)"); bool isTrue = false; if (isXPath) { isTrue = Policy .Handle<Exception>() .OrResult<bool>(r => r == false) .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3) }).Execute(() => { return browser.IsQuerySelector(tag, document); }); return isTrue; } else { isTrue = Policy .Handle<Exception>() .OrResult<bool>(r => r == false) .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3) }).Execute(() => { return browser.IsQuerySelector(tag); }); return isTrue; } } /// <summary> /// 检查标签是否存在 /// </summary> /// <param name="browser">浏览器对象</param> /// <param name="key">ini配置文件<k,v> k</param> /// <param name="path">ini配置文件路径</param> /// <param name="document">html文档(xpath才技持)</param> /// <returns></returns> public static bool CheckLabel(this IBrowser browser, string key, string path, string document = "document") { string tagText = INIHelper.Read("tag", key, path);//@"input[name=pass]"; tagText = string.IsNullOrWhiteSpace(tagText) ? INIHelper.Read("tagXPath", key, path) : tagText; var isXPath = Regex.IsMatch(tagText, "(^//.*)"); bool isTrue = false; if (isXPath) { isTrue = Policy .Handle<Exception>() .OrResult<bool>(r => r == false) .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3) }).Execute(() => { return browser.IsQuerySelector(tagText, document); }); return isTrue; } else { isTrue = Policy .Handle<Exception>() .OrResult<bool>(r => r == false) .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3) }).Execute(() => { return browser.IsQuerySelector(tagText); }); return isTrue; } }
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; } }
用法:
chromeBrowser.GetBrowser().GetBoundingClientRect("button[name=login]")
评论区