2010-08-17 92 views
1

我正在使用网络爬虫。我正在使用Webbrowser控件来达到此目的。我已经获得了存储在数据库中的URL列表,我想逐一遍历所有这些URL并解析HTML。C#Web浏览器控件:导航到列表到URL

我用下面的逻辑

  foreach (string href in hrefs) 
      { 
       webBrowser1.Url = new Uri(href); 
       webBrowser1.Navigate(href); 
      } 

我想要做的“webBrowser1_DocumentCompleted”事件的一些工作,一旦页面完全加载。但是“webBrowser1_DocumentCompleted”没有得到控制权,因为我在这里使用循环。只有在“hrefs”中的最后一个url被导航并且控件退出循环时它才会得到控制权。

什么是处理这种问题的最佳方法?

回答

4

将列表存储在您所在州的某处,以及您所需的索引。然后在DocumentCompleted事件中,解析HTML并导航到下一页。

(我个人不会用WebBrowser控制网页抓取......我知道这意味着它会处理JavaScript的你,但是这将是一个困难得多好听比并行使用多个WebRequestWebClient对象)。

1

首先,即使在加载任何内容之前,您都将新网址设置为相同的Web浏览器控件,这样您只需在浏览器中看到最后一个网址即可。浏览器肯定会花费一些时间来加载url,所以我猜在Document_Completed可以被触发之前导航已经被提前取消了。

只有一种办法同时做到这一点,

你必须使用一个标签控制,并打开一个新的标签项为每个URL和每个标签项目都会有它自己的web浏览器控件,你可以设置它的网址。

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(); 
    } 
} 
+0

+1您的队列方法的启发。我不确定他是否想要并行运行 - 我只是认为他希望在继续之前等待“完成”的循环。最好的祝福 – 2010-08-17 13:04:41