![](/img/trans.png)
[英]How to get HtmlDocument after jquery changes? (HtmlAgilityPack)
[英]Get HtmlDocument after javascript manipulations
在 C# 中,使用 System.Windows.Forms.HtmlDocument 類(或另一個允許 DOM 解析的類),是否可以等到網頁完成對 HTML 的 javascript 操作后再檢索該 HTML? 某些站點通過 javascript 將 innerhtml 添加到頁面,但是當我解析 HtmlDocument 的 HtmlElements 時,這些更改不會顯示。
一種可能性是在一秒鍾后更新頁面的 HtmlDocument。 有人知道怎么做這個嗎?
有人通過發布我認為不正確的答案來重新提出這個問題。 所以,這里是我的想法來解決它。
非確定性地,有可能接近找出頁面是否已完成其 AJAX 內容。 但是,這完全取決於該特定頁面的邏輯:有些頁面是永久動態的。
為了解決這個問題,可以先處理DocumentCompleted
事件,然后異步輪詢WebBrowser.IsBusy
屬性並監視頁面的當前 HTML 快照以進行更改,如下所示。
可以在此處找到完整的示例。
// get the root element
var documentElement = this.webBrowser.Document.GetElementsByTagName("html")[0];
// poll the current HTML for changes asynchronosly
var html = documentElement.OuterHtml;
while (true)
{
// wait asynchronously, this will throw if cancellation requested
await Task.Delay(500, token);
// continue polling if the WebBrowser is still busy
if (this.webBrowser.IsBusy)
continue;
var htmlNow = documentElement.OuterHtml;
if (html == htmlNow)
break; // no changes detected, end the poll loop
html = htmlNow;
}
一般來說,aswer 是“否” - 除非頁面上的腳本以某種方式通知您的代碼,否則您必須等待一段時間並獲取 HTML。 在文檔就緒通知之后等待一秒鍾,可能會覆蓋大多數站點(即 jQuery 的$(code)
案例)。
您需要給應用程序一些時間來處理 Java。 簡單地停止當前線程也會延遲 java 處理,因此您的文檔仍然會過時。
WebBrowserDocumentCompletedEventArgs cachedLoadArgs;
private void TimerDone(object sender, EventArgs e)
{
((Timer)sender).Stop();
respondToPageLoaded(cachedLoadArgs);
}
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
cachedLoadArgs = e;
System.Windows.Forms.Timer timer = new Timer();
int interval = 1000;
timer.Interval = interval;
timer.Tick += new EventHandler(TimerDone);
timer.Start();
}
我用 WEBBrowser 來看看我的班級:
public class MYCLASSProduct: IProduct
{
public string Name { get; set; }
public double Price { get; set; }
public string Url { get; set; }
private WebBrowser _WebBrowser;
private AutoResetEvent _lock;
public void Load(string url)
{
_lock = new AutoResetEvent(false);
this.Url = url;
browserInitializeBecauseJavascriptLoadThePage();
}
private void browserInitializeBecauseJavascriptLoadThePage()
{
_WebBrowser = new WebBrowser();
_WebBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
_WebBrowser.Dock = DockStyle.Fill;
_WebBrowser.Name = "webBrowser";
_WebBrowser.ScrollBarsEnabled = false;
_WebBrowser.TabIndex = 0;
_WebBrowser.Navigate(Url);
Form form = new Form();
form.Hide();
form.Controls.Add(_WebBrowser);
Application.Run(form);
_lock.WaitOne();
}
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
HtmlAgilityPack.HtmlDocument hDocument = new HtmlAgilityPack.HtmlDocument();
hDocument.LoadHtml(_WebBrowser.Document.Body.OuterHtml);
this.Price = Convert.ToDouble(hDocument.DocumentNode.SelectNodes("//td[@class='ask']").FirstOrDefault().InnerText.Trim());
_WebBrowser.FindForm().Close();
_lock.Set();
}
如果您嘗試在控制台應用程序中執行此操作,則需要將此標記放在 main 上方,因為 Windows 需要與 COM 組件進行通信:
[STAThread]
static void Main(string[] args)
我不喜歡這個解決方案,但我認為沒有人更好!
使用“WebBrowser.Navigated”事件怎么樣?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.