我正在编写一个抓取网站的程序。爬网功能是递归功能,可能会花费更多时间来完成,因此我使用多线程来执行多个网站的爬网。 我究竟需要的是,在完成抓取一个网站之后,它会调用下一个网站(应该在Queqe中),而不是一次抓取多个网站。 我正在使用C#和ASP.NET。
答案 0 :(得分:3)
执行此操作的标准做法是使用blocking queue。如果您使用的是.NET 4.0,那么您可以利用BlockingCollection类,否则您可以使用Stephen Toub的实现。
你要做的就是根据你的需要调整尽可能多的工作线程,然后让它们在队列中出现的无限循环中出现。你的主线程将列入项目。阻塞队列旨在等待/阻止出列操作,直到项目可用。
public class Program
{
private static BlockingQueue<string> m_Queue = new BlockingQueue<string>();
public static void Main()
{
var thread1 = new Thread(Process);
var thread2 = new Thread(Process);
thread1.Start();
thread2.Start();
while (true)
{
string url = GetNextUrl();
m_Queue.Enqueue(url);
}
}
public static void Process()
{
while (true)
{
string url = m_Queue.Dequeue();
// Do whatever with the url here.
}
}
}
答案 1 :(得分:2)
您想使用threadpool。
ThreadPool.QueueUserWorkItem(new WaitCallback(CrawlSite), (object)s);
您只需将工作负载“推送”到队列中,然后让线程池管理它。
答案 2 :(得分:1)
我必须说 - 我不是线程专家,而且我的C#非常生疏 - 但考虑到要求,我会建议这样的事情:
Crawler
个主题定义池。 Crawler
行为应该是这样的:
crawler
线程并使用子节点的地址在后台运行它我认为这里存在一些挑战 - 但作为一般流程,我相信它可以做到。
答案 3 :(得分:0)
将所有网址放入队列中,并在每次完成上一个网址时弹出一个网址。
您还可以将递归链接放入队列中,以便更好地控制您一次执行的下载次数。
您可以设置X个工作线程,这些线程都会从队列中获取一个url,以便一次处理更多。但是这样你就可以自己节制它。
您可以在.Net中使用ConcurrentQueue<T>
来获取可以使用的线程安全队列。