Comment générer dynamiquement du code HTML à l'aide de .NET et WebBrowser ou mshtml.HTMLDocument
Introduction
La génération dynamique de code HTML à l'aide de .NET offre flexibilité et contrôle sur le contenu des pages Web. Cet article explore deux approches pour récupérer du code HTML dynamique : utiliser la classe WebBrowser à partir de System.Windows.Forms et exploiter l'interface COM mshtml.HTMLDocument à partir de l'assembly de la bibliothèque d'objets HTML Microsoft.
Approche 1 : Utilisation WebBrowser
La classe WebBrowser est une option pratique pour charger des pages Web et accéder à leur contenu. Le code suivant montre comment charger une page et récupérer son code HTML à l'aide de l'événement WebBrowser DocumentCompleted :
<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>
Approche 2 : Utilisation de mshtml.HTMLDocument
Le mshtml. L'interface HTMLDocument offre un moyen direct d'interagir avec les documents HTML. Vous pouvez l'utiliser pour charger et accéder au HTML à partir d'une chaîne :
<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>
Limitations de WebBrowser et mshtml.HTMLDocument
Les approches WebBrowser et mshtml.HTMLDocument peuvent ne renvoie pas toujours le code HTML entièrement rendu. Pour résoudre ce problème, une approche améliorée utilisant des jetons async/wait et d’annulation est fournie en tant que réponse améliorée dans le contenu de référence. Cette approche surveille les modifications HTML de manière dynamique et récupère le contenu lorsqu'il est entièrement rendu.
Exemple de code
Le code optimisé suivant démontre l'approche améliorée :
<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>
Ce code garantit que la page est entièrement rendue avant de récupérer le contenu HTML, ce qui donne des résultats plus précis et fiables.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!