Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何最好地并行网页解析?_C#_.net_Multithreading_Parallel Processing - Fatal编程技术网

C# 如何最好地并行网页解析?

C# 如何最好地并行网页解析?,c#,.net,multithreading,parallel-processing,C#,.net,Multithreading,Parallel Processing,我正在使用html敏捷包解析论坛网站的各个页面。因此,解析方法返回页面链接上作为参数传递的所有主题/线程链接。我在一个集合中收集所有解析页面的所有主题链接 在那之后,我检查它们是否在我的字典中,如果它们不在,那么我将它们添加到一个新列表中,UI显示这个列表,这基本上是自上次以来创建的新主题/线程 既然所有这些操作看起来都是独立的,那么并行化的最佳方式是什么 我应该使用.NET 4.0的并行.For/ForEach 无论哪种方式,我如何在单个集合中收集每个页面的结果?或者这不是必须的 每当解析方法

我正在使用html敏捷包解析论坛网站的各个页面。因此,解析方法返回页面链接上作为参数传递的所有主题/线程链接。我在一个集合中收集所有解析页面的所有主题链接

在那之后,我检查它们是否在我的
字典中,如果它们不在,那么我将它们添加到一个新列表中,UI显示这个列表,这基本上是自上次以来创建的新主题/线程

既然所有这些操作看起来都是独立的,那么并行化的最佳方式是什么

我应该使用.NET 4.0的
并行.For/ForEach

无论哪种方式,我如何在单个集合中收集每个页面的结果?或者这不是必须的

每当解析方法完成时,我是否可以同时从我的集中式
字典中读取它们


如果我用4000页运行这个程序,大约需要90分钟,如果我能用我所有的8个内核在10分钟内完成同样的任务,那就太好了。

并行。for/ForEach
与在不同线程之间共享状态相结合似乎是实现这一点的好方法。并发字典确保多线程的安全读/写

在那之后,我检查它们是否在我已经查看过的URL字典中,如果没有,那么我将它们添加到一个新列表中,UI显示这个列表,这基本上是自上次以来创建的新主题/线程。 既然所有这些操作看起来都是独立的,那么并行化的最佳方式是什么

您当然可以使用Parallel.For/ForEach来实现这一点,但是您应该考虑一下爬虫程序的设计。大多数爬虫倾向于使用几个线程进行爬虫,每个线程都与一个页面获取客户端相关联,该客户端负责获取页面(在您的情况下,可能使用
WebRequest
/
WebResponse
),我建议您阅读以下文章:

  • (一篇11页的论文,读起来应该很轻松)
  • (一篇10页的论文,描述了一个在150Mbit连接上以每秒600页的速度爬行的爬虫程序)
如果您实现了
Mercator
设计,那么您应该可以轻松地以每秒50页的速度下载,因此您可以在80秒内下载4000页

无论哪种方式,我如何在单个集合中收集每个页面的结果

您可以将结果存储在
ConcurrentDictionary
中,就像Darin提到的那样。您不需要在值中存储任何内容,因为您的键将是link/URL,但是如果您正在执行一个函数,那么您可以将每个link/URL散列为一个整数,然后将散列存储为键,将link/URL存储为值

或者这不是必须的

这完全取决于您决定什么是必要的,但是如果您正在执行URL测试,那么它是必要的

每当解析方法完成时,我是否可以从我的集中式字典中读取数据,以查看它们是否同时存在

是的,
ConcurrentDictionary
允许多个线程同时读取,因此应该可以。如果您只想查看链接是否已被爬网,那么它可以正常工作

如果我运行这个4000页的程序,需要90分钟,如果我能用我所有的8个内核在10分钟内完成同样的任务,那就太好了


如果你的爬虫设计得足够好,你应该能够在一台普通的台式电脑上在大约57秒内下载和解析(提取所有链接)4000页。。。在4GB、i5、3.2 GHz、连接速度为10 Mbps的PC上,我使用标准的C#
WebRequest获得了大致的结果。

谢谢,你的意思是将解析页面中的所有链接存储在ConcurrentDictionary中,或者每次方法提取其链接时,它都会在我的集中集合中搜索新链接,这个集中的集合应该是一个ConcurrentDictionary吗?谢谢,Mercator设计对我来说可能有点复杂,但我将在一个
ConcurrentDictionary
中收集所有提取的链接,然后,在这之后,通过检查我的集中收集来收集新链接,我还想制作一个
ConcurrentDictionary
,这样我也可以并行完成这一步。这是我能想到的最好的了。