使用 .NET 的 WebBrowser 和 mshtml.HTMLDocument 擷取動態產生的 HTML
單獨使用 .NET 的 WebBrowser
或 mshtml.HTMLDocument
時,取得動態產生的 HTML 內容是一項挑戰。 一種更好的方法將兩者結合起來,如下面的程式碼範例所示:
<code class="language-csharp">using Microsoft.Win32; using System; using System.ComponentModel; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace WbFetchPage { public partial class MainForm : Form { public MainForm() { SetFeatureBrowserEmulation(); InitializeComponent(); this.Load += MainForm_Load; } // Initiate the asynchronous HTML retrieval async void MainForm_Load(object sender, EventArgs e) { try { var cts = new CancellationTokenSource(10000); // 10-second timeout var html = await LoadDynamicPage("https://www.google.com/#q=where+am+i", cts.Token); MessageBox.Show(html.Substring(0, 1024) + "..." ); // Display a truncated result } catch (Exception ex) { MessageBox.Show(ex.Message); } } // Asynchronous function to retrieve the HTML content async Task<string> LoadDynamicPage(string url, CancellationToken token) { // Navigate and wait for DocumentCompleted event 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 page load } finally { this.webBrowser.DocumentCompleted -= handler; } } // Get the root HTML element var documentElement = this.webBrowser.Document.GetElementsByTagName("html")[0]; // Asynchronously poll for HTML changes string html = documentElement.OuterHtml; while (true) { // Wait asynchronously (cancellation possible) await Task.Delay(500, token); // Continue polling if the browser is busy if (this.webBrowser.IsBusy) continue; string htmlNow = documentElement.OuterHtml; if (html == htmlNow) break; // No changes, exit loop html = htmlNow; } // Check for cancellation token.ThrowIfCancellationRequested(); return html; } // Enable HTML5 emulation (for IE10+) // More details: https://stackoverflow.com/a/18333982/1768303 static void SetFeatureBrowserEmulation() { if (LicenseManager.UsageMode != LicenseUsageMode.Runtime) return; var appName = System.IO.Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); Registry.SetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", appName, 10000, RegistryValueKind.DWord); } } }</code>
此程式碼使用 WebBrowser
進行導航,並使用 DocumentCompleted
事件進行初始頁面載入。 然後,它採用非同步輪詢機制 (Task.Delay()
) 來監視 OuterHtml
屬性的變更。 當沒有偵測到進一步的變更並且瀏覽器空閒時,循環終止,返回完全呈現的 HTML。 這種強大的方法可以有效地處理動態網頁內容。
以上是如何使用 .NET 的 WebBrowser 和 mshtml.HTMLDocument 高效能擷取動態產生的 HTML?的詳細內容。更多資訊請關注PHP中文網其他相關文章!