首頁  >  文章  >  web前端  >  如何不受限制地使用 .NET 檢索動態產生的 HTML 程式碼?

如何不受限制地使用 .NET 檢索動態產生的 HTML 程式碼?

Linda Hamilton
Linda Hamilton原創
2024-10-18 08:40:03923瀏覽

How to Retrieve Dynamically Generated HTML Code Using .NET without Limitations?

如何使用.NET的WebBrowser或mshtml.HTMLDocument動態產生HTML程式碼?

簡介

動態擷取HTML程式碼網頁產生是網路自動化和抓取場景中的常見任務。 .NET 提供了兩個選項來實現此目的:System.Windows.Forms.WebBrowser 類別和 mshtml.HTMLDocument 介面。然而,有效地使用它們可能具有挑戰性。

WebBrowser 類別

System.Windows.Forms.WebBrowser 類別旨在將網頁嵌入應用程式中。雖然它支援自訂導覽和文件事件,但捕獲動態生成的 HTML 的能力有限。

以下程式碼片段說明如何使用WebBrowser:

<code class="csharp">using System.Windows.Forms;
using mshtml;

namespace WebBrowserTest
{
    public class Program
    {
        public static void Main()
        {
            WebBrowser wb = new WebBrowser();
            wb.Navigate("https://www.google.com/#q=where+am+i");

            wb.DocumentCompleted += delegate(object sender, WebBrowserDocumentCompletedEventArgs e)
            {
                mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)wb.Document.DomDocument;
                foreach (IHTMLElement element in doc.all)
                {
                    System.Diagnostics.Debug.WriteLine(element.outerHTML);
                }
            };
            Form f = new Form();
            f.Controls.Add(wb);
            Application.Run(f);
        }
    }
}</code>

mshtml.HTMLDocument介面

mshtml.HTMLDocument介面

mshtml.HTMLDocument 介面提供對底層物件的直接訪問。但是,它需要手動導航和渲染,這使得動態生成內容不太方便。

<code class="csharp">using mshtml;

namespace HTMLDocumentTest
{
    public class Program
    {
        public static void Main()
        {
            mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)new mshtml.HTMLDocument();
            doc.write(new System.Net.WebClient().DownloadString("https://www.google.com/#q=where+am+i"));

            foreach (IHTMLElement e in doc.all)
            {
                System.Diagnostics.Debug.WriteLine(e.outerHTML);
            }
        }
    }
}</code>
以下程式碼片段說明如何使用mshtml.HTMLDocument:

更強大的方法

    要克服WebBrowser 和mshtml.限制,您可以使用以下方法:
  1. 建立WebBrowser 控制項。
  2. 導覽至目標 URL 並處理 DocumentCompleted 事件以取得底層 mshtml.HTMLDocument2 物件。
  3. 結合使用輪詢和檢查 WebBrowser.IsBusy 來偵測頁面何時完成渲染。
取得根元素並輪詢其 OuterHtml 屬性,直到其變得穩定。

範例程式碼

<code class="csharp">using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using mshtml;

namespace DynamicHTMLFetcher
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            this.webBrowser.DocumentCompleted += WebBrowser_DocumentCompleted;
            this.Load += MainForm_Load;
        }

        private async void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                var cts = new CancellationTokenSource(10000); // cancel in 10s
                var html = await LoadDynamicPage("https://www.google.com/#q=where+am+i", cts.Token);
                MessageBox.Show(html.Substring(0, 1024) + "..."); // it's too long!
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private async Task<string> LoadDynamicPage(string url, CancellationToken token)
        {
            var tcs = new TaskCompletionSource<bool>();
            WebBrowserDocumentCompletedEventHandler handler = (s, arg) => tcs.TrySetResult(true);

            using (token.Register(() => tcs.TrySetCanceled(), useSynchronizationContext: true))
            {
                this.webBrowser.DocumentCompleted += handler;
                try
                {
                    this.webBrowser.Navigate(url);
                    await tcs.Task; // wait for DocumentCompleted
                }
                finally
                {
                    this.webBrowser.DocumentCompleted -= handler;
                }
            }

            var documentElement = this.webBrowser.Document.GetElementsByTagName("html")[0];
            var html = documentElement.OuterHtml;
            while (true)
            {
                await Task.Delay(500, token);
                if (this.webBrowser.IsBusy)
                    continue;
                var htmlNow = documentElement.OuterHtml;
                if (html == htmlNow)
                    break; // no changes detected, end the poll loop
                html = htmlNow;
            }

            token.ThrowIfCancellationRequested();
            return html;
        }

        private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            // Intentional no-op handler, we receive the DocumentCompleted event in the calling method.
        }
    }
}</code>
以下C# 程式碼示範了此方法:

此方法可確保您取得完全呈現的HTML程式碼,即使它是動態生成的。

以上是如何不受限制地使用 .NET 檢索動態產生的 HTML 程式碼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn