vio*_*ech 7 ruby memory-leaks web-crawler mongodb anemone
我最近开始学习网络爬虫,我用Ruby,Anemone和Mongodb构建了一个样本爬虫来存储.我正在一个庞大的公共网站上测试爬虫,可能有数十亿个链接.
crawler.rb正在索引正确的信息,但是当我检查活动监视器中的内存使用情况时,它会显示内存不断增长.我只运行了爬虫大约6-7个小时,内存显示为1.38GB的mongod和1.37GB的Ruby进程.它似乎每小时左右增长约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
Run Code Online (Sandbox Code Playgroud)
我也遇到了这个问题,但我使用 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
Run Code Online (Sandbox Code Playgroud)
我将此处的补丁应用到 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,
Run Code Online (Sandbox Code Playgroud)
...
(以下内容曾在155号线)
157 page_queue = SizedQueue.new(@opts[:max_page_queue_size])
Run Code Online (Sandbox Code Playgroud)
我有一个每小时的 cron 工作:
#!/usr/bin/env python
import redis
r = redis.Redis()
r.flushall()
Run Code Online (Sandbox Code Playgroud)
尝试降低 Redis 的内存使用量。我现在正在重新启动一次巨大的爬行,所以我们将看看它进展如何!
我会报告结果...
| 归档时间: |
|
| 查看次数: |
2594 次 |
| 最近记录: |