首页新闻找找看学习计划

请教关于高速请求网页的方法

0
悬赏园豆:200 [已解决问题] 解决于 2013-01-06 13:53

类似网页爬行的程序,高速请求网页,一天可能要请求千万级别的程序,反正就是越快越好。假设电脑速度非常快,假设网络速度也非常快。i7cpu 16g内存,100m光纤独享等等。当然,如果不能提供这样的条件也要能跑。


有几个要求,第一要使用c# 写程序,如果要用其它语言,也只能把它做成模块让c#调用。第二,要稳定,不能自动退出,这程序要24小时运行。第三,要考虑请求的网页有各种问题,404,500错误,超时等等。

 

小的功力不够,使用System.Net下的 WebRequest ,加多线程,速度感觉不是很给力。容易闪退,不知道是为什么,另外速度也不够快,平均一分钟只能请求500个网页。有一些其它的工具远超过这个数。不知道他们是怎么做到。除了C或C++写的这个优势外,感觉还是有很多网络知识没精通。在这里肯请高手们赐教。

问题补充:

有人跟我说用socket 底层请求,不知道具体是怎么操作。不知道怎么个策略?

码有钱的主页 码有钱 | 初学一级 | 园豆:13
提问于:2012-12-29 22:03
< >
分享
最佳答案
0

要实现高性能和很多因素相关的,尤其是你这样的采集量比较大的

  1. 如 geass 所述,下载速度还取决于对方的网速,就算你的网速够快(如果你的网速不够快就不用采集了,天生残疾怎么都没治的)也不一定能达到最佳的速度,一般需要并发采集,并发时就要考虑并发控制了,根据具体情况可能还需要考虑多台机器负载分担。
  2. 多线程并发对小型采集任务来说还行,若你的采集任务并发数较大,线程的开销也不容忽视,对于大并发量应该考虑异步而不是多线程。
  3. 并发采集任务够多时,硬盘读写可能也成了瓶颈,可能还需要在内存中做buffer。

另外,对于同一个网站,如果你采集过于频繁,它可能也把你给封了,还要考虑突破网站限制。

最后,如果你只是光采集还比较简单,如果要一边采集,一边解析,同时根据解析结果生成新的采集任务,这个就要麻烦好几倍了,都可以起一个小项目了,不是很简单的能搞定的。

收获园豆:120
天方 | 大侠五级 |园豆:5264 | 2012-12-30 14:38

第二点,能不能再深入一些。

我是想做大批量请求,请求回来的html只是分析,分析完了就不要了。

其它因素我们是改不了的,我是想大批量请求网站,也有好的也有差的。只能考虑自己的程序怎么快。比如说对方的网比较慢,要有什么策略来请求。

码有钱 | 园豆:13 (初学一级) | 2012-12-30 21:21
其他回答(5)
0

你爬其他人网站,那也要看那些网站的网速等硬件配置,不能只是光看你这边的条件。

你跟其它工具对比都是爬同一个网站得出的结论。

geass.. | 园豆:1777 (小虾三级) | 2012-12-30 07:01

大批量请求,也有好的也有差的。不能考虑别人怎么样。只能考虑自己写的程序怎么快。

支持(0) 反对(0) 码有钱 | 园豆:13 (初学一级) | 2012-12-30 21:16

@goodfulcom: 容易闪退 一般是 异常没有处理。别人的网站也不是每秒都在发布新闻,真的需要这样高速,24小时运行,由于看不到你代码,不知道哪里可以优化。你反编译别人的程序参考下。另外,你指的“其它的工具远超过这个数” 是哪个工具,可以发给我参考下吗?

支持(0) 反对(0) geass.. | 园豆:1777 (小虾三级) | 2012-12-31 17:14

@geass..: 关于闪退的问题,举一个简单的例子:验证代理是否会成功,就会闪退,看如下代码:

 

while (!string.IsNullOrEmpty(line))
            {
                if (string.IsNullOrEmpty(line)) return;
                WebClient wc = new WebClient();
                wc.Proxy = new WebProxy(line);
                string s;
                try
                {
                    s = wc.DownloadString("http://www.google.com/search?hl=en&tbo=d&sclient=psy-ab&q=apple&btnG=");
                }
                catch (Exception)
                {
                    line = GetProxy();
                    continue;
                }
                if (s.IndexOf("www.apple.com") > 0)
                {
                    AddSuccess(line);
                    line = GetProxy();
                }
            }

这段代码让它多线程跑,多线程的关键代码如下:

            ThreadPool.SetMinThreads(305, 10);
            for (int i = 0; i < 300; i++)
                ThreadPool.QueueUserWorkItem(run, obj);

这里有一个参数一直不理解是什么意思 SetMinThreads的第二个参数 10。

感觉这些代码都很简单。就是会出现闪退。

支持(0) 反对(0) 码有钱 | 园豆:13 (初学一级) | 2012-12-31 20:55
0

采集的速度是一定的.你只能提高你的算法.

可以讲采集回来的数据交给另一个线程进行分析.

webrequest的高速访问往往导致被服务端给抛弃.所以你加一个判断,让它重新再获取一次.比如尝试3次

【秦时明月】 | 园豆:760 (小虾三级) | 2012-12-31 11:40
1

java有一些开源的框架,不过你的要求是c#

angelshelter | 园豆:9676 (大侠五级) | 2012-12-31 13:07
1

大批量的的请求可以使用.net的并发模型或task

闪退问题请检查你的处理代码

收获园豆:80
az235 | 园豆:8263 (大侠五级) | 2013-01-05 09:14
0

不过现在还有很多事ajax或者js渲染出来的,速度也许会更慢点

何必 | 园豆:47 (初学一级) | 2013-01-06 10:32
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册