CefSharp 滑动、输入、获取标签位置、点击等封装(支持XPath语法操作)

 /// <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]")






本文作者:admin

本文链接:https://www.javalc.com/post/90.html

版权声明:本篇文章于2022-02-24,由admin发表,转载请注明出处:分享你我。如有疑问,请联系我们

CefSharp Dom操作封装

发表评论

取消
扫码支持