Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.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
Javascript 是否有更有效的方法来刮取大量URL(>;30k)?_Javascript_Ruby_<img Src="//i.stack.imgur.com/RUiNP.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">elasticsearch_Phantomjs_Nokogiri - Fatal编程技术网 elasticsearch,phantomjs,nokogiri,Javascript,Ruby,elasticsearch,Phantomjs,Nokogiri" /> elasticsearch,phantomjs,nokogiri,Javascript,Ruby,elasticsearch,Phantomjs,Nokogiri" />

Javascript 是否有更有效的方法来刮取大量URL(>;30k)?

Javascript 是否有更有效的方法来刮取大量URL(>;30k)?,javascript,ruby,elasticsearch,phantomjs,nokogiri,Javascript,Ruby,elasticsearch,Phantomjs,Nokogiri,我经营一家网上商店,经营收藏品,其市场价格根据消费者需求不断变化 我最近开始记录我的竞争对手的价格,每天运行一个ruby脚本(rake任务),该脚本可以处理大约3万个URL的列表,获取一些相关的数据,并将它们填充到Elasticsearch索引中。我依靠Nokogiri和PhantomJS来实现这一点,因为不是所有的站点都能在不运行JavaScript的情况下正确呈现我需要的数据 我的程序目前在运行时消耗了大约4GB的内存,而PhantomJS占了大部分内存消耗(~2.5GB)。这个脚本也需要很

我经营一家网上商店,经营收藏品,其市场价格根据消费者需求不断变化

我最近开始记录我的竞争对手的价格,每天运行一个ruby脚本(rake任务),该脚本可以处理大约3万个URL的列表,获取一些相关的数据,并将它们填充到Elasticsearch索引中。我依靠Nokogiri和PhantomJS来实现这一点,因为不是所有的站点都能在不运行JavaScript的情况下正确呈现我需要的数据

我的程序目前在运行时消耗了大约4GB的内存,而PhantomJS占了大部分内存消耗(~2.5GB)。这个脚本也需要很多小时来运行——我不确定要运行多长时间,但我认为它需要10个多小时


我非常乐意接受关于如何减少内存消耗和提高我的刮取速度的建议。我希望我的竞争对手能为我提供一个漂亮的JSON API,但不幸的是,我们没有这种关系

我假设您在单线程上运行刮板(因为完成需要时间)。您应该考虑在多个线程上运行脚本。

在不影响吞吐量的情况下,您可以采取一些措施来提高刮取速率并保持较低的内存消耗

为了减少内存消耗,您可以将URL持久化到平面文件或数据库中,而不是通过数据结构将其放入内存中

还可以在几次迭代后清空数据结构中的任何数据

我假设您是按顺序发出请求,因为每次抓取URL所花费的平均时间大于1.2秒(10*60*60/30000=1.2)。您可以一次对一堆请求执行异步调用,因为您的代码将等待一个请求完成,直到它发出下一个请求

您可以参考“”,它涵盖了可伸缩刮取的大部分方面


这是我能给出的几个建议,因为我没有关于您的代码的任何信息。

最明显的工作是确定哪些站点需要完整的浏览器处理,哪些站点可以直接被删除,而不需要任何浏览器处理

第二件事是检查正在运行的JavaScript应用程序,看看是否有任何方法可以直接从它使用的API获取所需的数据。在客户端应用程序(例如Angular、React、Ember)中,通常会有某种JSON API与服务器进行通信。如果您可以直接与该API接口,它实际上大大简化了您的数据收集过程:您甚至可能根本不需要解析任何HTML

Ruby在处理事情方面通常相当不错,但它并不总是最高效的。需要考虑的是,如果使用JRuBy和线程可能会提高性能,通常它是在运行速度快40%的替换中的下降,但代价是较高的初始内存占用。 您可能还想探索使用Node.js执行大量获取/执行JavaScript的脏活的可行性,因为与Ruby的许多JavaScript运行时相比,Node.js非常轻量级。它甚至可以作为一个非常好的预取器,然后将内容移交给Ruby后端进行更多处理


使用数据库、Redis或RabbitMQ中间层作为队列或持久性机制,构建这样的混合系统非常容易。

我认为您应该节省时间,使用SaaS产品

  • 使用现有的、持续运行的超过8000万种产品的数据库,提供对产品定价和其他数据的访问。如果他们还没有你想要的数据,他们很可能有兴趣添加它
  • 根据您的参数提供按需定制web爬网。您可以随意抓取任意多个URL,然后通过API或仪表板获取数据
  • 提供定制的抓取和提取,并在其顶部提供一个光滑的用户界面。比如80条腿,加上相当健壮的内置提取功能。同样,设置它,随时抓取数据,并通过API或仪表板检索结果

我相信有一个时间和一个地方来推出你自己的功能。例如,如果出于估值原因,您希望将其构建为自己的知识产权,或者您认为这是组织的核心竞争力(即竞争优势)。但是,考虑到你需要它才能很好地工作,而不是爬行,这是一个站在别人肩膀上的好时机

在没有JavaScript的情况下可以抓取的站点上,实现一个替代路径。根据实际CPU负载增加并发限制。(另外,另一个1.5GB将走向何方?:-/)您要求我们根据您可以在互联网上搜索到的一般最佳实践提供意见。如果您需要特定信息,您必须向我们提供有关系统和代码的详细信息。请参阅“”和“”。不要运行每日脚本,请在辅助代码中连续运行刮削,并使用适当的限制。记住,做一个好的网民意味着不打别人的主机或他们的带宽;使用HTTP HEAD请求查看他们的页面自上次查看以来是否发生了更改。我可以保证您可以在不使用PhantomJS的情况下获取价格数据。我从来没有见过一家商店需要Javascript来清理,我已经做了数千次了。@pguardiario-是的,我想你是对的。。。我一直在更仔细地查看每个站点,以了解如何消除对phantom的依赖,为HTTP创建一个特别好的并行处理组合。实际上,我刚刚开始使用平面文件,而不是在内存中保留这么多信息。Th