使用 .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中文网其他相关文章!