【问题标题】:Ruby, Mongodb, Anemone: web crawler with possible memory leak?Ruby、Mongodb、Anemone:可能存在内存泄漏的网络爬虫?
【发布时间】:2012-02-22 12:46:06
【问题描述】:

我最近开始学习网络爬虫,我用 Ruby 构建了一个示例爬虫,AnemoneMongodb 用于存储。我正在一个可能包含数十亿个链接的大型公共网站上测试爬虫。

crawler.rb 正在索引正确的信息,尽管当我在活动监视器中检查内存使用情况时,它显示内存不断增长。我只运行了爬虫大约 6-7 个小时,内存显示 mongod 为 1.38GB,Ruby 进程为 1.37GB。它似乎每小时增长约 100MB。

看来我可能有内存泄漏?它们是否是一种更优化的方式,我可以在不失控内存升级的情况下实现相同的爬网,从而可以运行更长时间?

# Sample web_crawler.rb with Anemone, Mongodb and Ruby.

require 'anemone'

# do not store the page's body.
module Anemone
  class Page
    def to_hash
      {'url' => @url.to_s,
       'links' => links.map(&:to_s),
       'code' => @code,
       'visited' => @visited,
       'depth' => @depth,
       'referer' => @referer.to_s,
       'fetched' => @fetched}
    end
    def self.from_hash(hash)
      page = self.new(URI(hash['url']))
      {'@links' => hash['links'].map { |link| URI(link) },
       '@code' => hash['code'].to_i,
       '@visited' => hash['visited'],
       '@depth' => hash['depth'].to_i,
       '@referer' => hash['referer'],
       '@fetched' => hash['fetched']
      }.each do |var, value|
        page.instance_variable_set(var, value)
      end
      page
    end
  end
end


Anemone.crawl("http://www.example.com/", :discard_page_bodies => true, :threads => 1, :obey_robots_txt => true, :user_agent => "Example - Web Crawler", :large_scale_crawl => true) do | anemone |
  anemone.storage = Anemone::Storage.MongoDB

  #only crawl pages that contain /example in url
  anemone.focus_crawl do |page|
    links = page.links.delete_if do |link|
      (link.to_s =~ /example/).nil?
    end
  end

  # only process pages in the /example directory
  anemone.on_pages_like(/example/) do | page |
    regex = /some type of regex/
    example = page.doc.css('#example_div').inner_html.gsub(regex,'') rescue next

    # Save to text file
    if !example.nil? and example != ""
      open('example.txt', 'a') { |f| f.puts "#{example}"}
    end
    page.discard_doc!
  end
end

【问题讨论】:

  • 你找出泄漏的原因了吗?如果您认为这是 Anemone 中的错误,您是否在他们的 issue tracker 上报告过?
  • 在 Anemone 问题跟踪器中提到的相关问题包括:memory leak?memory leak or inefficient memory handlingFixes OutOfMemory error for large sites
  • 我报告它的时间与在 SO 上发帖的时间差不多。通过添加建议的修复程序,我能够抓取我的任务所需的内容,并且它使我的抓取持续时间更长,尽管内存使用量稳步增长,只是没有以前那么快。我仍然不确定导致内存泄漏的原因。

标签: ruby mongodb memory-leaks web-crawler anemone


【解决方案1】:

我也有这个问题,但我使用 redis 作为数据存储。

这是我的爬虫:

require "rubygems"

require "anemone"

urls = File.open("urls.csv")
opts = {discard_page_bodies: true, skip_query_strings: true, depth_limit:2000, read_timeout: 10} 

File.open("results.csv", "a") do |result_file|

  while row = urls.gets

    row_ = row.strip.split(',')
    if row_[1].start_with?("http://")
      url = row_[1]
    else
      url = "http://#{row_[1]}"
    end 
    Anemone.crawl(url, options = opts) do |anemone|
      anemone.storage = Anemone::Storage.Redis
      puts "crawling #{url}"    
      anemone.on_every_page do |page| 

        next if page.body == nil 

        if page.body.downcase.include?("sometext")
          puts "found one at #{url}"     
          result_file.puts "#{row_[0]},#{row_[1]}"
          next

        end # end if 

      end # end on_every_page

    end # end crawl

  end # end while

  # we're done
  puts "We're done."

end # end File.open

我将 here 中的补丁应用到我在 anemone gem 中的 core.rb 文件:

35       # Prevent page_queue from using excessive RAM. Can indirectly limit ra    te of crawling. You'll additionally want to use discard_page_bodies and/or a     non-memory 'storage' option
36       :max_page_queue_size => 100,

...

(以下内容曾经在第 155 行)

157       page_queue = SizedQueue.new(@opts[:max_page_queue_size])

我有一个每小时的 cron 工作:

#!/usr/bin/env python
import redis
r = redis.Redis()
r.flushall()

尝试降低 redis 的内存使用量。我现在正在重新开始一个巨大的爬行,所以我们会看看它是怎么回事!

我会报告结果...

【讨论】:

    【解决方案2】:

    我正在做类似的事情,我认为您可能只是在创建大量数据。

    你不是在拯救身体,所以这应该有助于记忆需求。

    我能想到的唯一其他改进是使用 Redis 而不是 Mongo,因为我发现它对于 Anemone 的存储来说更具可扩展性。

    检查您在 mongo 中的数据大小 - 我发现我保存了大量行。

    【讨论】:

      猜你喜欢
      • 2011-01-07
      • 1970-01-01
      • 1970-01-01
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      相关资源
      最近更新 更多