c#爬虫程序中多线程的问题

哨子 2010-11-21 05:31:08
这几天自己写了个爬虫程序,感觉运行不快,同样一个网站,我用XENU采集,可达到1000页/分,自己写的却只能达到150页/分,估计是线程中的问题,同时开10个线程,在监测中平均只有3个处在Running状态中,其它都是处于WaitSleepJoin状态中,不知道哪位高手能帮忙看一下.

//采集的主线程代码
#region 下载所有链接
private string ReadUrl()
{
//读取待采集地址
string url = null;
for (int i = 0; i < lst.Items.Count; i++)
{
if (lst.Items[i].SubItems[3].Text == "等待")
{
url = lst.Items[i].SubItems[2].Text;
return url;
}
}
return url;
}
/// <summary>
/// 开始下载所有链接
/// </summary>
private void GetLinks()
{

string url = ReadUrl();
//读取URL,如果多次没有URL,则停止线程的运行
if (url == null)
{
NoHref++;
if (NoHref > ThreadNumber * 4)
Thread.CurrentThread.Abort();
Thread.Sleep(1000);
GetLinks();
}
//更新UI,和更改下载状态
lst.Invoke(new WeiTuo(UpdateDowningStatus), new object[] { url, Thread.CurrentThread.Name, "下载中…" });
string content = CaiJi.GetWebPage(url, Ecd);
FileLength += content.Length;

DownedUrls = array.ArrayAddItem(DownedUrls, url);
if (content.Length == 0)//如果返回内容为空,则递归
{
lst.Invoke(new WeiTuoError(DownError), new object[] { url, content });
GetLinks();
}
if (content.IndexOf("Error:") != -1)
{
if (content.IndexOf("远程服务器") > 0)
content = "404";
else
content = "TimeOut";
lst.Invoke(new WeiTuoError(DownError), new object[] { url, content });
GetLinks();
}
lst.Invoke(new WeiTuo(UpdateDowningStatus), new object[] { url, Thread.CurrentThread.Name, "完成" });
ViewItemsAdd(content, url);
Thread.Sleep(0);
GetLinks();
}
#endregion

//用于采集的程序
...全文
204 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
哨子 2010-11-26
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 whrspsoft3723 的回复:]
一些“笨重”线程,会点用本机的大部分资源,其它的线程只能等待了。验证一下。
[/Quote]
嗯,这个是重点,我把程序中耗内存的操作和许多不是采集必须的操作去掉后,快多了。
谢谢。
whrspsoft3723 2010-11-21
  • 打赏
  • 举报
回复
[Quote=引用楼主 shaochengtian 的回复:]
这几天自己写了个爬虫程序,感觉运行不快,同样一个网站,我用XENU采集,可达到1000页/分,自己写的却只能达到150页/分,估计是线程中的问题,同时开10个线程,在监测中平均只有3个处在Running状态中,[/Quote]

只看到这些代码,不足以解决你的问题。
谈谈自己的体会吧:
(1) 网站是否允许你连这么多的线程 。作个对比试验, 再运行一个你这个程序的副本*共2个副本,也开10个线程,看几个在等待。如果都在等待,
(2)你的带宽够吧,那三个线程把带宽占完了,后边的只有等待了,看下带宽有没有空余。
(3) 一些“笨重”线程,会点用本机的大部分资源,其它的线程只能等待了。验证一下。
(4)你有没有“重复”读取网页,你如果排除那些重复的? 如果它不读重复的,也不读未过期的,那他有3000页也不过分(3000页全是新抓下来的吗)确认下。

管中窥豹,仅供参考 。
描述:由C#编写的多线程异步抓取网页的网络爬虫控制台程序 功能:目前只能提取网络链接,所用的两个记录文件并不需要很大。网页文本、图片、视频和html代码暂时不能抓取,请见谅。 但需要注意,网页的数目是非常庞大的,如下代码理论上大概可以把整个互联网网页链接都抓下来。 但事实上,由于处理器功能和网络条件(主要是网速)限制,一般的家用电脑最多能胜任12个线程左右的抓取任务,抓取速度有限。可以抓取,但需要时间和耐心。 当然,这个程序把所有链接抓下来是可能的,因为链接占系统空间并不多,而且有记录文件的帮助,已抓取网页的数量可以堆积下去, 甚至可以把所有的互联网网络链接都存取下来,当然,最好是分批次。建议设置maxNum为500-1000左右,慢慢累积下去。 另外因为是控制台程序,有时候显示字符过多会系统会暂停显示,这时候只要点击控制台按下回车键就可以了。程序假死的时候,可以按回车键(Enter)试试。 /// 使用本程序,请确保已创建相应的记录文件,出于简化代码的考虑,本程序做的并不健壮,请见谅。 /// 默认的文件创建在E盘根目录“已抓取网址.txt”和“待抓取网址.txt”这两个文本文件,使用者需要自行创建这两个文件,注意后缀名不要搞错。 这两个文件里面的链接基本都是有效链接,可以单独处理使用。 本爬虫程序的速度如下: 10线程最快大概500个链接每分钟 6-8线程最快大概400-500个链接每分钟 2-4线程最快大概200-400个链接每分钟 单线程最快大概70-100个链接每分钟 之所以用多线程异步抓取完全是出于效率考虑,本程序多线程同步并不能带来速度的提升,只要抓取的网页不要太多重复和冗余就可以,异步并不意味着错误。

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧