Extraction du HTML généré dynamiquement à l'aide du navigateur Web de .NET et de mshtml.HTMLDocument
La récupération de contenu HTML généré dynamiquement présente un défi lors de l'utilisation de WebBrowser
ou mshtml.HTMLDocument
.NET individuellement. Une méthode supérieure combine les deux, comme le montre l'exemple de code ci-dessous :
<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>
Ce code utilise le WebBrowser
pour naviguer et l'événement DocumentCompleted
pour le chargement initial de la page. Il utilise ensuite un mécanisme d'interrogation asynchrone (Task.Delay()
) pour surveiller les modifications apportées à la propriété OuterHtml
. La boucle se termine lorsqu'aucun autre changement n'est détecté et que le navigateur est inactif, renvoyant le HTML entièrement rendu. Cette approche robuste gère efficacement le contenu Web dynamique.
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!