3

我正在用 Ruby 构建一个网络爬虫,Rails 作为前端。我正在使用建立在 Nokogiri 之上的 Mechanize。我已经实现了一个可以抓取网页的解决方案,但我希望能够在一次运行中抓取 200k 个网站,我知道有比等待数小时完成更好的方法。我希望能够通过启动并行请求而不使其过于复杂来实现最佳性能。我对线程一无所知,它有什么限制,所以如果有人想指出我可以在哪里学习如何做到这一点,或者至少告诉我应该做什么,请不要在爬虫运行时劫持服务器寻找。请记住,我将写入数据库和文件(可能我可以在爬网完成后从数据库中导出,而不是直接写入文件)。谢谢。

注意:这里有一个类似的问题,但是已经有几年了,也许人们现在的做法有所不同,而且看起来很复杂。

4

3 回答 3

5

看看使用Typhoeus 和 Hydra。它们将使并行处理 URL 变得容易。

您不需要使用 Mechanize,除非您必须从每个页面请求特殊数据。对于普通的爬虫,您可以使用 Open::URI 和 Nokogiri 抓取主体并解析它,而无需 Mechanize 的开销或附加功能。出于您的目的,将 Typhoeus 替换为 Open::URI 并让 Hydra 处理线程管理。

请记住,如果您尝试一次全部完成,爬取 200k 个网站将会使您的带宽饱和。这将使您的 Rails 站点不可用,因此您需要限制您的请求。而且,这意味着您将不得不在几个(或多个)小时内完成它们。速度并不像在此处保持您的网站在线那么重要。我可能会将爬虫放在与 Rails 服务器不同的机器上,并让数据库将所有东西联系在一起。

创建一个表或文件,其中包含您要抓取的网站 URL。我推荐这个表格,这样您就可以整理一个表格来编辑/管理 URL。您需要跟踪以下内容:

  • 上次抓取 URL 的时间。(约会时间)
  • 是否应抓取特定 URL(布尔值或字符1
  • URL(字符串或 var char[1024] 应该没问题)。这应该是唯一的键。
  • 当前是否正在抓取该 URL(布尔值或字符1)。这在所有记录的运行开始时被清除,然后在蜘蛛加载该页面时设置并离开。
  • 显示什么时候可以运行该站点的字段。
  • 显示可以运行该站点的时间的字段。

最后两个很重要。您不想抓取一个功率不足的小站点并终止其连接。这是被禁止的好方法。

创建另一个表作为下一个 URL,以检查从您在爬网时遇到的链接收集的特定站点。您需要提出一个规范化例程,以将带有会话数据和参数的 URL 简化为可用于测试唯一性的东西。在这个新表中,您希望 URL 是唯一的,这样您就不会陷入循环或不断添加具有不同参数的同一页面。

您可能需要注意在任何重定向之后检索到的实际登录 URL,而不是“获取”URL,因为重定向和 DNS 名称在站点内可能会有所不同,并且生成内容的人可能使用不同的主机名。同样,您可能希望在 head 块中查找元重定向并遵循它们。这些是做你想做的事情的一个特别令人讨厌的方面。

当您遇到新的 URL 时,请检查它们是否正在退出 URL,如果您关注它们,这将导致您离开该站点。如果是这样,请不要将它们添加到您的 URL 表中。

将数据库信息写入文件可能无济于事,因为要找到正确的文件,您可能无论如何都需要进行数据库搜索。只需将您需要的内容存储在字段中并直接请求即可。200K 行在数据库中算不了什么。

注意网站的“蜘蛛”规则,如果他们提供 API 来获取数据,请使用它,而不是爬行。

于 2012-09-24T19:32:05.963 回答
3

我不是 Ruby 专家,但这里有一些基于其他编程语言经验的想法和答案:

A. 您必须了解 Web 服务器或运行 Ruby 应用程序的环境的线程模型。
例如,我正在使用一个名为 tomcat 的 Web 服务器,它可以配置它打开的线程数。
当然,这不能超过操作系统上可能的线程数。

B. 此外,请记住,由于您需要“爬行”,这意味着您可能需要处理文件(即 - Linux 上的文件描述符),而这些资源是有限的。
例如,在 Linux 上,您可以使用 ulimit 配置文件描述符的限制。

C. 我会认真地推荐你有一个线程池(我确信 Ruby 有这方面的框架,这我在谷歌搜索时想到的)。
使用线程池,意味着您正在使用线程,但您没有打开/关闭线程,而是有一组线程,从共享数据结构中提取作业并执行它们。
例如,您可以做的是,对于每个作业,您将执行以下伪代码:
1. 解析网页
2. 对于每个链接执行:
2.1。使用 URL 创建作业。
2.2 将作业放在队列中(以便线程池线程工作)

我也会认真考虑使用集群(例如 - 云上的几台机器)并开发可扩展的解决方案。
这意味着您将在集群节点之间拥有某种共享数据结构(可能是数据库或 NoSQL DB),并且您的工作线程将提取作业,并将新作业放入这种集群方式(云方式)共享数据结构中.
我还建议您阅读有关map-reduce模式的信息,它可以在此处为您提供帮助,
并且可能将 Hadoop 与 Ruby 结合使用(请参阅此处的链接)。


再次抱歉,我不是 ruby​​ 专家,但我在使用的其他计算机语言中遇到了您的问题。
我希望我给了你一些提示和阅读材料。祝你好运!

于 2012-09-22T18:56:52.507 回答
0

检查http://anemone.rubyforge.org/index.html

我认为它可能适合您的需求,如果不是,您应该能够从它的源代码中学到很多东西。

于 2012-09-22T19:02:23.870 回答