网页爬虫,用户输入一批网址加入未爬取队列,多线程进行爬取。提取网页里的链接又加入到未爬取队列。循环往复。那我的运行逻辑是使用并发集合ConcurrentQueue,开启线程循环取任务,访问网址提取源码里的A标签链接再加入到未爬取队列。 以下是我的代码框架,我想知道有没有更好的方法。
class Spider
{
//未爬取队列
private static ConcurrentQueue<string> _queue = new ConcurrentQueue<string>() ;
/// <summary>
/// 设置初始化未爬取的链接
/// </summary>
public void SetLink(string[] m_link)
{
foreach (var item in m_link)
{
_queue.Enqueue(item);
}
}
/// <summary>
/// 启动爬行
/// </summary>
public void Start()
{
//启动50个线程循环取任务
for (int i = 0; i < 50; i++)
{
Task.Factory.StartNew(() =>
{
while (true)
{
string link;
if (_queue.TryDequeue(out link))
{
GetLink(link);
}
Thread.Sleep(1);
}
},TaskCreationOptions.LongRunning);
}
}
//访问链接进行提取
private void GetLink(string link)
{
string html = httpRequest(link);//获取源码后进行提取
//...然后把提取到链接又加回到 _queue里
}
}
不建议公用一个队列,锁竞争会非常大,GetLink 方法内最好再放入一个新队列
我就看到了死循环