【问题标题】:Getting HTML body content in WinForms WebBrowser after body onload event executes正文 onload 事件执行后在 WinForms WebBrowser 中获取 HTML 正文内容
【发布时间】:2022-03-07 21:05:07
【问题描述】:

我在 WinForms 中有一个 WebBrowser 控件,其 URL 属性设置为外部网页。我还有一个 DocumentCompleted 事件的事件处理程序。在这个处理程序中,我试图获取特定元素,但 wb.Document.Body 似乎在执行 onload 之前捕获了 HTML。

{System.Windows.Forms.HtmlElement}
    All: {System.Windows.Forms.HtmlElementCollection}
    CanHaveChildren: true
    Children: {System.Windows.Forms.HtmlElementCollection}
    ClientRectangle: {X = 0 Y = 0 Width = 1200 Height = 0}
    Document: {System.Windows.Forms.HtmlDocument}
    DomElement: {mshtml.HTMLBodyClass}
    ElementShim: {System.Windows.Forms.HtmlElement.HtmlElementShim}
    Enabled: true
    FirstChild: null
    htmlElement: {mshtml.HTMLBodyClass}
    Id: null
    InnerHtml: "\n"
    InnerText: null
    Name: ""
    NativeHtmlElement: {mshtml.HTMLBodyClass}
    NextSibling: null
    OffsetParent: null
    OffsetRectangle: {X = 0 Y = 0 Width = 1200 Height = 0}
    OuterHtml: "<body onload=\"evt_Login_onload(event);\" uitheme=\"Web\">\n</body>"
    OuterText: null
    Parent: {System.Windows.Forms.HtmlElement}
    ScrollLeft: 0
    ScrollRectangle: {X = 0 Y = 0 Width = 1200 Height = 0}
    ScrollTop: 0
    shimManager: {System.Windows.Forms.HtmlShimManager}
    ShimManager: {System.Windows.Forms.HtmlShimManager}
    Style: null
    TabIndex: 0
    TagName: "BODY"

"&lt;body onload=\"evt_Login_onload(event);\" uitheme=\"Web\"&gt;\n&lt;/body&gt;" 是 JavaScript 之前的内容。有没有办法在evt_Login_onload(event);执行后捕获body标签的状态?

我也尝试过使用wb.Document.GetElementById("id"),但它返回null。

【问题讨论】:

    标签: c# html winforms webbrowser-control onload


    【解决方案1】:

    这是怎么做的,我已经把一些 cmets 内联了:

    private void Form1_Load(object sender, EventArgs e)
    {
        bool complete = false;
        this.webBrowser1.DocumentCompleted += delegate
        {
            if (complete)
                return;
            complete = true;
            // DocumentCompleted is fired before window.onload and body.onload
            this.webBrowser1.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
                    MessageBox.Show("window.onload was fired, can access DOM!");
                }, null);
            });
        };
    
        this.webBrowser1.Navigate("http://www.example.com");
    }
    

    更新,现在是 2019 年,这个答案令人惊讶地仍然受到关注,所以我想指出,我推荐的使用现代 C# 的方法是使用 async/await,例如 this .

    【讨论】:

    • +1 我可以确认这个答案对我有用,虽然我不需要使用SyncronizationContext.Current.Post(),因为我正在运行单线程。
    • @StevendeSalas,SyncronizationContext.Current.Post 的全部目的是从 onload 事件处理程序返回并在同一个 UI 线程上异步继续(因此不会在 MSHTML 代码中引发任何可能的异常触发事件)。从那时起,代码有了一些发展,改用async/awaitexample
    • 我尝试了类似的方法-但没有奏效..你能看看stackoverflow.com/questions/22697987/…吗?
    • @Lijo,检查一下:stackoverflow.com/a/22262976/1768303。访问那里列出的所有链接。
    猜你喜欢
    • 2014-03-29
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    相关资源
    最近更新 更多