抓取500万个网页的最有效的方法(时间,成本)?


8

我有一个网页列表,我需要对其进行抓取,解析然后将结果数据存储在数据库中。总数约为500万。

我目前对实现此目标的最佳方法的假设是部署约100个EC2实例,为每个实例提供50,000页以供抓取,然后继续运行,然后在该过程完成后将数据库合并在一起。假设运行大约需要一天(加载,解析和保存每个页面需要600毫秒)。

有没有人有在有限的时间内进行如此大量的页面抓取的经验?我之前(150万)做了大量工作,但是那是在一台机器上完成的,只花了一周多的时间就完成了。

我遇到的瓶颈是页面的下载,解析所需的时间不超过2毫秒,因此我正在寻找可以简化页面下载过程的内容。


当您说网页列表时,这只是一个普通网页还是整个网站,例如论坛或其他内容?另外,即使您
大胆尝试,

我有多个实例,这个答案与我相关,出于问题的考虑,我给出了一个可以轻易可视化的任意图形,并且网页的类型各不相同,但是对于这个问题,可以假定它是一个正在被废弃的论坛如果你喜欢。该网站是否允许抓取是一个无关紧要的问题(无论如何都是这个问题)
山姆

为了阐明有关网页类型的要点:每个网页都彼此独立,可以按任何顺序进行抓取,并且不依赖于要抓取的另一个。可以向前,向后,随机进行,这无关紧要。
山姆

我知道了。我不知道EC2如何处理下载,但是一些经验丰富的SF用户可能会有一些想法。另外,也是题外话,但这是MinecraftForums 柠檬酸吗?这是一个相当独特的名称。
tombull89'2011/

mmhmm是I。–
sam,

Answers:


7

在假设下载时间(以及带宽使用量)是您的限制因素的假设下,我将提出以下建议:

首先,选择m1.large实例。在I / O性能的三个“级别”(包括带宽)中,m1.large和m1.xlarge实例均提供“高” I / O性能。由于您的任务不受CPU限制,因此,其中成本最低的将是首选。

其次,您的实例将能够以比任何站点都能提供页面服务的速度快得多的速度下载-不要一次在给定实例上下载单个页面,而是同时运行任务-您应该能够同时至少执行20页(尽管,我想您大概可以轻松完成50-100次)。(以从您的评论中从论坛下载为例-这是一个动态页面,这将花费服务器时间来生成-并且其他用户正在使用该站点的带宽等)。继续增加并发性,直到达到实例带宽的限制。(当然,不要同时向同一站点发出多个请求)。

如果您确实想最大程度地提高性能,则可以考虑在地理位置上适当的区域中启动实例以最大程度地减少延迟(但这将需要对所有URL进行地理定位,这可能不切实际)。

需要注意的一件事是实例带宽是可变的,有时您将获得更高的性能,而在其他时候您将获得更低的性能。在较小的实例上,性能差异更为显着,因为物理链接由更多服务器共享,并且其中任何一个都会减少可用带宽。在EC2网络(相同可用性区域)内的m1.large实例之间,您应该获得接近理论的千兆吞吐量。

通常,使用AWS时,与较大的实例相比,与多个较小的实例相比,效率几乎总是更高的(除非您专门查看需要多个实例的故障转移之类的东西)。

我不知道您的设置需要什么,但是当我以前尝试进行此操作(在1到2百万个链接之间,并定期更新)时,我的方法是维护一个包含添加新链接的链接数据库,并进行分叉过程刮和解析页面。将检索(随机)URL,并在数据库上将其标记为正在进行中,脚本将下载该页面;如果成功,则将该URL标记为已在数据库中下载,并将内容发送到另一个解析该页面的脚本,新链接被添加到数据库中。这里的数据库的优点是集中化-多个脚本可以同时查询数据库,并且(只要事务是原子的)就可以确保每个页面仅下载一次。

还有两点值得一提-一次可以运行的按需实例数量有限制(我相信20个)-如果您打算超过这些限制,则需要请求AWS来增加您帐户的限制。对于您来说,运行现货实例并在现货价格较低时扩大数量(可能是一个按需实例以保持一切有序,其余的现货实例)则更为经济。

如果时间的优先级高于成本,那么群集计算实例将提供10Gbps带宽-并应产生最大的下载带宽。

总结:尝试几个大型实例(而不是许多小型实例)并在每个实例上运行多个并发下载-如果发现自己的带宽有限,则添加更多实例,如果发现自己的CPU /内存受限,则移至更大的实例。


4

我们尝试做类似的事情,这是我的5美分:

  1. 获得2-3台便宜的非计量服务器,例如,不支付带宽费用。

  2. 将python与asyncore一起使用。Asyncore是做事的老方法,但是我们发现它的工作速度比其他任何方法都快。缺点是DNS查找被阻止,即不是“并行”。使用asyncore,我们设法使用单个XEON 4核,8 GB RAM刮取了1M URL 40分钟。服务器上的平均负载小于4(这对于4核来说非常好)。

  3. 如果您不喜欢异步,请尝试使用gevent。它甚至可以进行DNS非阻塞。使用gevent,在相同的硬件上将1M下载了大约50分钟。服务器上的平均负载很大。

请注意,我们确实测试了许多Python库,例如grequests,curl,liburl / liburl2,但并未测试Twisted

  1. 我们确实测试了PHP + curl +几个进程,它完成了大约一个小时的工作,但是服务器上的平均负载却很大。

根据我的经验,“无限制”通常是指“我们会在感觉到时将您拒之门外”。
ceejayoz 2015年

以我的经验,“未计量”是指上限为100 MBit
Nick
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.