【问题标题】:Inspect element from my WPF WebBrowser, using "inspect element(s)"(IE,Chrome,Firefox) to get the css path("copy css-path")从我的 WPF WebBrowser 检查元素,使用“检查元素”(IE、Chrome、Firefox)来获取 css 路径(“复制 css-path”)
【发布时间】:2015-08-28 15:02:36
【问题描述】:

我需要来自网页的正确 css 路径,该路径将显示在我的 WPF 应用程序中(稍后与 HTMLAgilityPack 和/或 Fizzler 一起使用)。

类似this,“复制css-path”或xpath(FireBug),应该是最终目标。

我还发现了一些有趣的帖子,例如:

他们都使用“webBrowser.Document.GetElementFromPoint”、“webBrowser.GetElementFromPoint”或“PointToClient”,但我在任何库中都找不到它,甚至在msdn.microsoft(WebBrowser Class)上也找不到

顺便说一句,我使用 Visual Studio 2010 工具箱中的“WebBrowserControl”来显示我的网页。

然后我在客户端找到了一些功能,但这不可能是他们的意思(javascript)...

更新时间:6 月 12 日,晚上 8:15

这其实是个不错的post by "dick"

    private void myBrowser_LoadCompleted(object sender, NavigationEventArgs e)
{
    dynamic doc = myBrowser.Document;
    dynamic htmlText = doc.documentElement.InnerHtml;
    string htmlstring = htmlText;
}

这可行,但这与我的 WPF 元素无关。 我只得到 html 但没有得到相应的元素。 我可以在那个 html 文档中搜索文本,但如果它出现多次,它就不再是唯一的了。

更新时间:6 月 13 日,上午 7:15

根据this 教程,我找到了解决方法。

我在我的“.xaml”中包含了这个命名空间:

xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

然后我添加了旧的winforms浏览器:

<WindowsFormsHost Name="wfhSample" Margin="372,12,12,205" MouseLeftButtonDown="wfhSample_MouseLeftButtonDown">
    <WindowsFormsHost.Child>
        <wf:WebBrowser />
    </WindowsFormsHost.Child>
</WindowsFormsHost>

为我的“MainWindow()”添加了一个起始值:

MainWindow(){
 (wfhSample.Child as System.Windows.Forms.WebBrowser).Navigate("http://www.google.de/");
 }

实际部分,获取元素:

 /*
    System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
    ...myMethod(..., (wfhSample.Child as System.Windows.Forms.WebBrowser), point.X, point.Y);
    */
     ...myMethod(...,System.Windows.Forms.WebBrowser refWebBrowser2,Int32 valScreenX, Int32 valScreenY,....){

    Point refPoint = refWebBrowser2.PointToClient(new Point(valScreenX, valScreenY));

    System.Windows.Forms.HtmlElement refHtmlElement = refWebBrowser2.Document.GetElementFromPoint(refPoint); //System.Drawing()

    return refHtmlElement.TagName;
    }

现在剩下的唯一问题是事件处理程序没有触发(我在属性窗口中添加了它们):

//winforms-browser
                    private void wfhSample_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            MessageBox.Show("old");

        }

        //wpf-browser
                private void browser_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            MessageBox.Show("new");

        }

为什么我不能覆盖事件处理程序(甚至是右键)?

更新时间:6 月 13 日上午 7:45

This 可能是一篇有用的文章,我会检查一下。

更新时间:6 月 16 日上午 7:00

现在我找到了一个解决方案,我可以处理 wpf-webbrowser 的事件,但不能处理旧的 winforms-browser。

    //new WPF webbrowser  
      private void browser_LoadCompleted(object sender, NavigationEventArgs e)
            {
                mshtml.HTMLDocument doc;
                doc = (mshtml.HTMLDocument)browser.Document;
                mshtml.HTMLDocumentEvents2_Event iEvent;
                iEvent = (mshtml.HTMLDocumentEvents2_Event)doc;
                iEvent.onclick += new mshtml.HTMLDocumentEvents2_onclickEventHandler(NewClickEventHandler);
            }

             private bool NewClickEventHandler(mshtml.IHTMLEventObj e)
            {
            //the click event handler works, but I have no access to "GetElementFromPoint"
 // it does not exist
                        //Point refPoint = browser.PointToClient(new Point(valScreenX, valScreenY));
                //System.Windows.Forms.HtmlElement refHtmlElement = browser.Document.GetElementFromPoint(refPoint);
                //return refHtmlElement.TagName;
                //because the new wpf control does not support for example 'GetElementFromPoint()'
            // I need to get the html controls conntected to the wpf cursor
            }

This 帮助了我,我将 wpf 应用程序中 Winforms webbrowser 的事件处理更改为:

//old Winforms webbrowser
        private void wfhSample_ChildChanged(object sender, System.Windows.Forms.Integration.ChildChangedEventArgs e)
        {
        //registering the event here, 
        //calling "OldClickEventHandler" does not work I get a "NullReferenceException" for "_docEvent"
         HTMLDocumentEvents2_Event _docEvent= (HTMLDocumentEvents2_Event)(wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument;
            _docEvent.onclick += new HTMLDocumentEvents2_onclickEventHandler(OldClickEventHandler);
        }
                    private bool OldClickEventHandler(mshtml.IHTMLEventObj e)
            {
            }

目前我仍然没有从我在 WPF 应用程序中选择的 webbrowser 中获取元素,一方面我遇到了旧 webforms webbrowser 的事件问题,我得到一个“NullReferenceException”(实际上从我的角度来看,它不应该为空),另一方面,对于我的新(wpf)网络浏览器控件,我无法访问“Ge​​tElementFromPoint()”,因为它对于 wpf 网络浏览器控件似乎不存在。

更新时间:6 月 17 日上午 10:00

看来,

(HTMLDocumentEvents2_Event)(wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument;

里面的“wfhSample_ChildChanged”还没有准备好,因为当我放同样的语句时:

(HTMLDocumentEvents2_Event)(wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument;

进入“NewClickEventHandler(mshtml.IHTMLEventObj e)”,其中包含所需的数据(但这是错误的事件处理程序)。

所以,现在我需要为我的旧 wpf 浏览器找到正确/合适的事件处理程序。

更新时间:6 月 17 日,上午 11:30

好的,现在我根据this文章找到了解决方案,我将代码改为:

   private void wfhSample_Loaded(object sender, RoutedEventArgs e)
    {
        bool complete = false;
        (wfhSample.Child as System.Windows.Forms.WebBrowser).DocumentCompleted += delegate
        {
            if (complete)
                return;
            complete = true;
            // DocumentCompleted is fired before window.onload and body.onload
            (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.Window.AttachEventHandler("onload", delegate
            {
                // Defer this to make sure all possible onload event handlers got fired
                System.Threading.SynchronizationContext.Current.Post(delegate
                {
                    // try webBrowser1.Document.GetElementById("id") here
                    //System.Windows.MessageBox.Show("window.onload was fired, can access DOM!");
                    var bla = (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument;
                    HTMLDocumentEvents2_Event _docEvent = (HTMLDocumentEvents2_Event)(wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument;
                    _docEvent.onclick += new HTMLDocumentEvents2_onclickEventHandler(OldClickEventHandler);
                }, null);
            });
        };

        (wfhSample.Child as System.Windows.Forms.WebBrowser).Navigate("http://www.example.com");
    }
    private bool OldClickEventHandler(mshtml.IHTMLEventObj e)
    {
        System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
        System.Drawing.Point refPoint = (wfhSample.Child as System.Windows.Forms.WebBrowser).PointToClient(new System.Drawing.Point(point.X, point.Y));
        System.Windows.Forms.HtmlElement refHtmlElement = (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.GetElementFromPoint(refPoint);
        var restult = refHtmlElement.TagName; //this is what I need for the first time,to continue
        return true;
    }

旧控件的事件处理有效:)

但是“var restult = refHtmlElement.TagName;”返回“NullReferenceException”,坐标似乎有问题。

一旦我有解决方案,我会发布它,或者如果您有想法,您也可以提供帮助:)

【问题讨论】:

    标签: c# wpf .net-4.0 webbrowser-control


    【解决方案1】:

    好的,我在我的 wpf 应用程序中找到了一个包括 winform webbrowser 的解决方案(看看我关于进程和资源的问题):

    1. .xaml 部分(命名空间)(more details):

    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    

    2..xaml 部分(WebBrowser)(more details):

    <WindowsFormsHost Name="wfhSample" Margin="372,12,12,205" Loaded="wfhSample_Loaded">
        <WindowsFormsHost.Child>
            <wf:WebBrowser />
        </WindowsFormsHost.Child>
    </WindowsFormsHost>
    

    3.文件背后的代码(more details):

       private void wfhSample_Loaded(object sender, RoutedEventArgs e)
        {
            bool complete = false;
            (wfhSample.Child as System.Windows.Forms.WebBrowser).DocumentCompleted += delegate
            {
                if (complete)
                    return;
                complete = true;
                // DocumentCompleted is fired before window.onload and body.onload
                (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.Window.AttachEventHandler("onload", delegate
                {
                    // Defer this to make sure all possible onload event handlers got fired
                    System.Threading.SynchronizationContext.Current.Post(delegate
                    {
                        // try webBrowser1.Document.GetElementById("id") here
                        //System.Windows.MessageBox.Show("window.onload was fired, can access DOM!");
                        var bla = (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument;
                        HTMLDocumentEvents2_Event _docEvent = (HTMLDocumentEvents2_Event)(wfhSample.Child as System.Windows.Forms.WebBrowser).Document.DomDocument;
                        _docEvent.onclick += new HTMLDocumentEvents2_onclickEventHandler(OldClickEventHandler);
                    }, null);
                });
            };
    
            (wfhSample.Child as System.Windows.Forms.WebBrowser).Navigate("http://www.example.com");
        }
        private bool OldClickEventHandler(mshtml.IHTMLEventObj e)
        {
            System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
            System.Drawing.Point refPoint = (wfhSample.Child as System.Windows.Forms.WebBrowser).PointToClient(new System.Drawing.Point(point.X, point.Y));
            System.Windows.Forms.HtmlElement refHtmlElement = (wfhSample.Child as System.Windows.Forms.WebBrowser).Document.GetElementFromPoint(refPoint);
            var restult = refHtmlElement.TagName; 
            return true;
        }
    

    4.要获得完整的 CSS-Path 或 XPath,您可以使用 Fizzler、HTMLAgilityPack(this)。

    有时会出现一些问题(调整窗口大小、更改选项卡),事件处理程序不再触发。

    【讨论】:

      猜你喜欢
      • 2012-09-07
      • 1970-01-01
      • 2011-04-06
      • 2014-11-01
      • 2011-06-19
      • 2014-07-03
      • 2013-08-24
      • 2018-01-20
      相关资源
      最近更新 更多