以 HTML 格式获取当前的 WebBrowser DOM
Posted
技术标签:
【中文标题】以 HTML 格式获取当前的 WebBrowser DOM【英文标题】:Get current WebBrowser DOM as HTML 【发布时间】:2013-09-19 11:30:57 【问题描述】:我想在加载了我需要的所有内容的 WebBrowser 上使用 html 功能包(它单击带有代码的按钮以加载频道上的每个视频) (它加载一个 YouTube 频道,然后加载该频道上的所有视频。) 现在,如果我尝试获取所有视频详细信息(我有一个将频道的前 30 个视频放入列表视图的工作代码),它仍将仅显示前 30 个,但我已在 WebBrowser 页面上加载了所有视频(它显示所有视频) 我正在使用它来获取当前从 WebBrowser 加载的内容
但它仍然只加载前 30 个视频,而不是从 WebBrowser 加载的所有视频。
【问题讨论】:
您是否受制于您当前使用的技术? PhantomJS 真的很擅长处理这样的事情。 将返回页面初始加载时的 Html,而不是使用 ajax 动态添加的任何内容 我如何获得动态加载的内容? 【参考方案1】:如果目标网站大量使用 AJAX(如 Youtube 那样),则很难(如果不是不可能)确定页面何时完成加载和执行所有动态脚本。但是您可以通过处理window.onload
事件并为非确定性 AJAX 调用留出一两秒钟的时间来接近。然后通过dynamic
调用webBrowser.Document.DomDocument.documentElement.outerHTML
获取当前渲染的HTML。
例子:
private void Form1_Load(object sender, EventArgs e)
DownloadAsync("http://www.example.com").ContinueWith(
(task) => MessageBox.Show(task.Result),
TaskScheduler.FromCurrentSynchronizationContext());
async Task<string> DownloadAsync(string url)
TaskCompletionSource<bool> onloadTcs = new TaskCompletionSource<bool>();
WebBrowserDocumentCompletedEventHandler handler = null;
handler = delegate
this.webBrowser.DocumentCompleted -= handler;
// attach to subscribe to DOM onload event
this.webBrowser.Document.Window.AttachEventHandler("onload", delegate
// each navigation has its own TaskCompletionSource
if (onloadTcs.Task.IsCompleted)
return; // this should not be happening
// signal the completion of the page loading
onloadTcs.SetResult(true);
);
;
// register DocumentCompleted handler
this.webBrowser.DocumentCompleted += handler;
// Navigate to url
this.webBrowser.Navigate(url);
// continue upon onload
await onloadTcs.Task;
// artificial delay for AJAX
await Task.Delay(1000);
// the document has been fully loaded, can access DOM here
return ((dynamic)this.webBrowser.Document.DomDocument).documentElement.outerHTML;
[EDITED]这是帮助解决 OP 问题的最后一段代码:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(((dynamic)this.webBrowser1.Document.DomDocument).documentElement.outerHTML);
【讨论】:
呜呜。我有一个按钮,在页面加载并通过点击进行 AJAX 调用后,它会使用该页面。这个答案让我很困惑。 糟糕,我误读了有关您如何加载页面的部分,抱歉。只需使用最后一部分获取当前页面 HTML 快照:((dynamic)this.webBrowser.Document.DomDocument).documentElement.outerHTML
而不是 webBrowser.DocumentText
。
在清除非法字符的代码后,我得到了这个i.imgur.com/58cGnZB.png
outerHTML
返回一个字符串,将其与HtmlAgilityPack
一起使用,如下所示:doc.LoadHtml(((dynamic)this.webBrowser.Document.DomDocument).documentElement.outerHTML)
。
得到它的工作我使用了你的第一个代码,然后用 htmlabilitypack Ty 加载HTML! HtmlAgilityPack.HtmlDocument 文档 = 新 HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(((动态)this.webBrowser1.Document.DomDocument).documentElement.outerHTML);以上是关于以 HTML 格式获取当前的 WebBrowser DOM的主要内容,如果未能解决你的问题,请参考以下文章