【发布时间】:2014-05-23 17:04:19
【问题描述】:
我们目前为无法向我们提供 xml 文件的客户使用网络爬虫。该列表正在建立,因此我需要一种更有效的方式来抓取这些站点。爬虫的逻辑很简单:
Pass in www.example.com/widgets
Store the html and pass it to crawler function
crawl widgets page 1
IF widgets page 1 is the end of their product list
stop
else
go to widgets page 2
这对队列中的每个站点重复。如您所见,如果站点 1 有 5000 个产品,则站点 2 在完成之前无法继续。多线程的最佳方法是什么,以便我可以限制我对每个站点发出多少请求,但一次抓取多个站点?我尝试了 Parallel.ForEach,但结果非常零星且不可预测。目前,我们通过启动“组”商店并同时使用 Windows 任务管理器来处理此问题。这是一些示例代码:
foreach(site in ListofSites)
{
int page = 1;
bool continue_crawling = true;
while(continue_crawling)
{
HtmlDocument doc = new HtmlDocument();
var htmlWeb = new HtmlWeb();
htmlWeb.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";
doc = htmlWeb.Load(URL + page);
string html = doc.DocumentNode.OuterHtml;
continue_crawling = ParseFile(html);
page++;
}
}
private bool Parse(string html)
{
//parse the file and see if we have enough data
return endofproduct;
}
【问题讨论】:
-
您是想一次通过多个请求访问同一个站点,还是只在一个线程中处理每个站点(但同时访问多个站点)?
-
我想限制我对每个站点的请求,这样我就不会压倒他们。如果我对每个站点有多个请求,一旦一个线程找到其产品列表的末尾,我将需要一种方法来停止其他线程。总体而言,最有效的就是我们要追求的目标。两者的结合甚至是一种选择。正确的数据是最重要的部分。如果我们的爬虫错过了他们产品的页面,客户会很生气。
标签: c# .net multithreading asynchronous web-crawler