我正在使用网络抓取工具。我正在使用Webbrowser控件来实现此目的。我已经将数据库列表存储在数据库中,我想逐个遍历所有这些URL并解析HTML。
我使用了以下逻辑
foreach (string href in hrefs)
{
webBrowser1.Url = new Uri(href);
webBrowser1.Navigate(href);
}
一旦完全加载页面,我想在“webBrowser1_DocumentCompleted”事件中做一些工作。但是“webBrowser1_DocumentCompleted”没有得到控件,因为我在这里使用循环。只有当“hrefs”中的最后一个url被导航并且控件退出循环时,它才会获得控件。
处理此类问题的最佳方法是什么?
答案 0 :(得分:4)
将列表存储在您所在州的某个位置,以及您所在位置的索引。然后在DocumentCompleted
事件中,解析HTML,然后导航到下一页。
(我个人不会使用WebBrowser
控件来进行网页抓取......我知道这意味着它会为你处理JavaScript,但要比使用多个版本更好地并行化将会困难得多WebRequest
或WebClient
个对象。)
答案 1 :(得分:1)
首先,您将新网址设置为相同的网络浏览器控件,甚至在它加载任何内容之前,这样您只需在浏览器上看到最后一个网址即可。肯定浏览器肯定会花一些时间来加载网址,所以我猜想导航会在事先解除Document_Completed之前提前取消。
只有一种方法可以同时执行此操作,
您必须使用标签控件,并为每个网址打开一个新的标签项,每个标签项都有自己的网络浏览器控件,您可以设置其网址。
foreach(string href in hrefs){
TabItem item = new TabItem();
WebBrowser wb = new WebBrowser();
wb.DocumentCompleted += wb_DocumentCompleted;
wb.Url = href;
item.Child = web;
tabControl1.Items.Add(item);
}
private void wb_DocumentCompleted(object sender, EventArgs e){
/// do your stuff...
}
为了改进上述方法,你应该看看如何在不同的UI线程中创建多个标签项,这里讨论的是漂亮的日志主题,但仍然可以。
另一种方法是使用队列......
private static Queue<string> queue = new ...
foreach(string href in hrefs){
queue.Enqueue(href);
}
private void webBrowser1_DocumentCompleted(object sender, EventArgs e){
if(queue.Count>0){
webBrowser1.Url = queue.Dequeue();
}
}