如何加快通过url循环下载网站的html源代码?
我正在使用此代码下载,但速度很慢。 (平均下载时间〜每个网址5秒)
using (WebClient client = new WebClient())
{
for (int i = 0; i <= 20; i++)
{
var source_code = client.DownloadString(url[i]);
}
}
答案 0 :(得分:2)
您显然无法加快每次下载速度,但您可以并行下载多个网址的内容。有很多方法可以做到这一点,这里有一个使用Parallel.ForEach
:
var urls = new List<string>() { "http://www.google.com", "http://www.stackoverflow.com" };
var results = new ConcurrentDictionary<string, string>();
Parallel.ForEach(urls, url =>
{
using (var webClient = new WebClient())
{
results[url] = webClient.DownloadString(url);
}
});
结果以URL作为键存储在ConcurrentDictionary
中,因此在循环完成后,您可以提取下载的代码。您可能需要添加一些代码来引入错误处理,并可能添加一些合理的超时,但我希望这会给您一个想法。
答案 1 :(得分:1)
要发布其他选项,例如目前为止的答案,这里的版本仅使用HttpClient
方法中async
的一个实例,您基本上可以分离20个作业并获取HTML内容从这些工作中的URL开始,一旦工作开始,你就可以等待所有工作完成。
我将此问题与其他答案一起发布的原因是,如果您使用HTTP客户端,则每个URL不需要多个客户端实例。
private async Task GetAuctionData()
{
List<Task> tasks = new List<Task>();
using (var client = new HttpClient())
{
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
var downloadTask = Task.Run(() =>
{
// Perform work here on HttpClient
});
tasks.Add(downloadTask);
}
await Task.WhenAll(tasks);
}
}
答案 2 :(得分:0)
如果您正在从20个不同的网址中抓取数据,并且如果这些调用都不依赖于其他网址,那么为什么要在循环中执行此操作?为什么不使用20个不同的Web客户端制作20个不同的asynchronous calls?然后,当它们全部完成后,您可以将结果拼接在一起。
类似的东西:
// Start the HandleFile method.
Task<string> task1 = ScrapeUrl(url1);
Task<string> task2 = ScrapeUrl(url2);
Task<string> task3 = ScrapeUrl(url3);
...
// Control returns here before scraping is done.
Console.WriteLine("Please wait patiently...");
// Wait for the scraping tasks to complete.
// ... Display its results.
string result1 = await task1;
string result2 = await task2;
string result3 = await task3;
...