gpt4 book ai didi

c# - .net 4.0 中并行化网络爬虫的最佳实践

转载 作者:行者123 更新时间:2023-11-30 13:48:55 24 4
gpt4 key购买 nike

我需要通过代理下载很多页面。构建多线程网络爬虫的最佳做法是什么?

Parallel.For\Foreach 是否足够好,还是更适合繁重的 CPU 任务?

您对以下代码有何看法?

var multyProxy = new MultyProxy();

multyProxy.LoadProxyList();


Task[] taskArray = new Task[1000];

for(int i = 0; i < taskArray.Length; i++)
{
taskArray[i] = new Task( (obj) =>
{
multyProxy.GetPage((string)obj);
},

(object)"http://google.com"
);
taskArray[i].Start();
}


Task.WaitAll(taskArray);

它的工作非常糟糕。它非常慢,我不知道为什么。

此代码也无法正常工作。

 System.Threading.Tasks.Parallel.For(0,1000, new System.Threading.Tasks.ParallelOptions(){MaxDegreeOfParallelism=30},loop =>
{
multyProxy.GetPage("http://google.com");
}
);

嗯,我认为我做错了什么。

当我启动我的脚本时,它只使用 2%-4% 的网络。

最佳答案

您基本上是将 CPU 绑定(bind)线程用于 IO 绑定(bind)任务 - 即。即使您正在并行化您的操作,它们本质上仍会用完一个 ThreadPool 线程,该线程主要用于 CPU 绑定(bind)操作。

基本上您需要使用异步模式来下载数据以将其更改为使用 IO 完成端口 - 如果您使用的是 WebRequest,则使用 BeginGetResponse() 和 EndGetResponse() 方法

我建议查看 Reactive Extensions 来执行此操作,例如:

IEnumerable<string> urls = ... get your urls here...;
var results = from url in urls.ToObservable()
let req = WebRequest.Create(url)
from rsp in Observable.FromAsyncPattern<WebResponse>(
req.BeginGetResponse, req.EndGetResponse)()
select ExtractResponse(rsp);

其中 ExtractResponse 可能只是使用 StreamReader.ReadToEnd 来获取字符串结果,如果这就是您想要的

您还可以查看使用 .Retry 运算符,如果遇到连接问题等,这将很容易让您重试几次...

关于c# - .net 4.0 中并行化网络爬虫的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10688359/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com