.NET と WebBrowser または mshtml.HTMLDocument を使用して HTML コードを動的に生成する方法
はじめに
.NET を使用して HTML コードを動的に生成すると、Web ページのコンテンツを柔軟に制御できるようになります。この記事では、動的 HTML コードを取得するための 2 つのアプローチについて説明します。1 つは System.Windows.Forms から WebBrowser クラスを利用する方法、もう 1 つは Microsoft HTML オブジェクト ライブラリ アセンブリから COM インターフェイス mshtml.HTMLDocument を利用する方法です。
アプローチ 1: 利用するWebBrowser
WebBrowser クラスは、Web ページをロードしてそのコンテンツにアクセスするための便利なオプションです。次のコードは、WebBrowser DocumentCompleted イベントを使用してページを読み込み、その HTML を取得する方法を示しています。
<code class="csharp">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); } };</code>
アプローチ 2: mshtml.HTMLDocument の利用
mshtml。 HTMLDocument インターフェイスは、HTML ドキュメントを直接操作する方法を提供します。これを使用して、文字列から HTML を読み込んでアクセスできます。
<code class="csharp">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>
WebBrowser と mshtml.HTMLDocument の制限
WebBrowser と mshtml.HTMLDocument の両方のアプローチでは、必ずしも完全にレンダリングされた HTML コードを返すとは限りません。これに対処するために、async/await およびキャンセル トークンを使用した改善されたアプローチが、リファレンス コンテンツの拡張応答として提供されています。このアプローチでは、HTML の変更を動的に監視し、完全にレンダリングされたときにコンテンツを取得します。
コード サンプル
次の最適化されたコードは、改善されたアプローチを示しています。
<code class="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; } 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); } } 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; html = htmlNow; } token.ThrowIfCancellationRequested(); return html; } 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>
このコードは、HTML コンテンツを取得する前にページが完全にレンダリングされることを保証し、より正確で信頼性の高い結果をもたらします。
以上が.NET を使用して HTML コードを動的に生成するアプローチは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。