正文 onload 事件执行后在 WinForms WebBrowser 中获取 HTML 正文内容

Posted

技术标签:

【中文标题】正文 onload 事件执行后在 WinForms WebBrowser 中获取 HTML 正文内容【英文标题】:Getting HTML body content in WinForms WebBrowser after body onload event executes 【发布时间】: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。

【问题讨论】:

【参考方案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/await,example。 我尝试了类似的方法-但没有奏效..你能看看***.com/questions/22697987/…吗? @Lijo,检查一下:***.com/a/22262976/1768303。访问那里列出的所有链接。

以上是关于正文 onload 事件执行后在 WinForms WebBrowser 中获取 HTML 正文内容的主要内容,如果未能解决你的问题,请参考以下文章

多个事件绑定执行window.onload写法

onload 事件

事件绑定及深入上-多个window.onload

防止在Winforms C#中右键单击文本框

onload事件追加函数

从javascript onload事件执行managebean方法