.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 が返されます。 この堅牢なアプローチは、動的 Web コンテンツを効果的に処理します。
以上が.NET の WebBrowser と mshtml.HTMLDocument を使用して、動的に生成された HTML を効率的に取得する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。