EKsumic's Blog

let today = new Beginning();

Click the left button to use the catalog.

OR

CefSharp向浏览器中指定DOM发送点击事件?想操作的网页没有用JQuery怎么办?

相信你翻到了不少抄袭或转载https://www.cnblogs.com/yidanda888/p/12614308.html的文章,

这个代码我就再贴出来一遍:

/// <summary>
/// 模拟点击指定选择符DOM元素
/// </summary>
/// <param name="selector">jQuery选择符</param>
private void ClickElement(string selector)
{
    var sSel = $"$('{selector}').offset();";
    Task<CefSharp.JavascriptResponse> t = Browser.EvaluateScriptAsync(sSel);
    t.Wait();
    if (t.Result.Result != null)
    {
        var expandoDic = t.Result.Result as IDictionary<string, object>;
        if ((null != expandoDic) && expandoDic.ContainsKey("left") && expandoDic.ContainsKey("top"))
        {
            var left = Convert.ToInt32(expandoDic["left"]) + 5;
            var top = Convert.ToInt32(expandoDic["top"]) + 5;

            Browser.GetBrowserHost().SendMouseClickEvent(left, top, MouseButtonType.Left, false, 1, CefEventFlags.None);
            Browser.GetBrowserHost().SendMouseClickEvent(left, top, MouseButtonType.Left, true, 1, CefEventFlags.None);
        }
    }
}

原理是先借助jQuery获取指定DOM的偏移,然后发送SendMouseClickEvent完成模拟点击操作。

 

那么问题来了,如果

你想操作的网页没有用JQuery怎么办?

于是你开始寻找,你可能会找到在这篇文档:

C# – Cefsharp winforms:将jquery注入页面

试了一下,然后非常失望地离开了,(至少我是这样的/(ㄒoㄒ)/~~),

然后拼命寻找方法,结果怎么找都找不到。

 

我是如何按照上面的答案做的?

我存储了一个1.txt文本,里面写着:

(function () {
    // more or less stolen form jquery core and adapted by paul irish
    function getScript(url, success) {
        var script = document.createElement('script');
        script.src = url;
        var head = document.getElementsByTagName('head')[0],
            done = false;
        // Attach handlers for all browsers
        script.onload = script.onreadystatechange = function () {
            if (!done && (!this.readyState
                || this.readyState == 'loaded'
                || this.readyState == 'complete')) {
                done = true;
                success();
                script.onload = script.onreadystatechange = null;
                head.removeChild(script);
            }
        };
        head.appendChild(script);
    }
    getScript('http://code.jquery.com/jquery-latest.min.js', function () {
        if (typeof jQuery == 'undefined') {
            console.log('Sorry, but jQuery wasn\'t able to load');
        } else {
            console.log('This page is now jQuerified with v' + $.fn.jquery);

            $(document).ready(function () {
                alert(1);
                //here you can write your jquery code
            });
        }
    });
})();

接着用:

browser.ExecuteScriptAsync(script)

执行。

然后发现并没有起任何作用。

于是,我尝试将上面的script代码放到控制台中,结果它给我返回了错误:

Error

说一定要在服务器端运行,The requset has been blocked。

我尝试很多网站,包括我自己的,我发现以上的script是一定不能在console里面执行的。你想执行它的唯一方法是把最后的小括号删除,这样console会显示:

demo

但是仍然不起作用,你还是用不起来JQuery,我尝试了offset()方法:

demo

很显然不起任何作用。


不过后来直接想到了一个最简单的方法:

https://www.v2know.com/MainPage/PreView/442

既然CefSharp的ExecuteScriptAsync是模拟console的行为,那么javascript的命令是可以完全执行的,对于在得到html文本里面附加一段jquery是一定可以的。

browser.ExecuteScriptAsync(script)

执行以上网址提到的第一个script即可。


后记:

CefSharp从65.0版本之后好像开始越来越隐藏DOM节点树了,CefSharp本身开始更加偏向于模拟Chrome内核,可能作者认为,所有的操作不应当以他的说明文档为准,他在极力脱离自己的方法,使得大家只要会JavaScript就可以使用CefSharp,所以本质上是可以理解的。

DOM是隐藏的,不像Winform原生控件Web Browser可以直接用方法得到DOM节点元素。

 

参考文档:

[1] https://www.cnblogs.com/yidanda888/p/12614308.html

[2] https://www.voidcn.com/article/p-mmuhfuxp-bwa.html

This article was last edited at 2021-01-18 12:36:23

* *