Раздел «Язык Ruby».RubySchoolSourceL06:
<<Программирование на Ruby

Занятие 6: Инструмент для скачивания сайтов

Следующее занятие
Предыдущее занятие

Домашнее задание

Net::HTTP.get

require 'net/http'
require 'uri'

url = "http://acm.mipt.ru/twiki/bin/view/Ruby/RubySchoolSource"

html = Net::HTTP.get(URI.parse(url))

puts html # сам HTML текст

puts html.scan(%r{http://[^\s><''""]+}) # ссылки, которые встречаются на странице

Добавим работа с кодировкой сайта

require 'net/http'
require 'uri'
require 'iconv'

url = "http://acm.mipt.ru/twiki/bin/view/Ruby/RubySchoolSource"
html = Net::HTTP.get(URI.parse(url))

begin 
  html = Iconv.iconv('koi8r//ignore', 'utf-8', html).join
rescue =>e
  puts e.to_s
end

puts html # сам HTML текст

puts html.scan(%r{http://[^\s''""><]+}) # ссылки, которые встречаются на странице

Черновой код скачивалки с ошибками (для доработки дома)

require 'net/http'
require 'uri'
require 'iconv'

url = 'http://acm.mipt.ru/twiki/bin/view/Ruby/RubySchoolSource'

# очень черновой вариант метода вычисления имени файла из URL
def url_to_filename(url, target_dir)
  uri = URI.parse(url)
  # нужно добавить защиту от '../../../etc/passwd' и др. подобных вещей
  path = File.join(target_dir, uri.path.gsub(/\W/, '_') + '.html')
  # Если вы хотите сохранять структуру сайта, то не нужно
  # заменять слеши на подчеркивание.
  # Для создания пути используйте FileUtils.mkdir_p()
end

def load_url(initial_url, http=nil, initial_level=5, target_dir = '.')
  queue = [ [initial_url, initial_level] ]
  initial_uri = URI.parse(initial_url)
  loaded_url = {}
  queued_url = {}
  
  http = Net::HTTP.start(initial_uri.host, initial_uri.port) unless http && http.alive?
  
  while !queue.empty?
    
    url,level = queue.shift
    
    puts "Downloading #{url}"
    puts "Current queue: #{queue.size}"
    puts "Queued: #{queued_url.size}"
    puts "Downloaded: #{loaded_url.size}"
    
    next if loaded_url[url]
    uri = URI.parse(url)
    
    puts "Path = "  + uri.path
    result = http.get( (uri.path != '') ? uri.path : '/' )
    html = result.body
    
    # Кодировку страницы нужно получать из result
    # и перекодировать в utf-8, если она отличается от utf-8
    #begin 
    #  html = Iconv.iconv('koi8r//ignore', 'utf-8', html).join
    #rescue =>e
    #  puts e.to_s
    #end
    
    # Нужна умная функция вычисляющая имя файла по URL
    file_name = url_to_filename(url, target_dir)
    
    File.open(file_name, 'w+') do |file|
      puts "Saving '#{url}' to #{file_name}"
      file.write(html)
      loaded_url[url] = 1
    end

    if level > 0
      html.scan(%r{http://[^\s"'><]+}).each do |sub_url|
        # puts sub_url
        next if queued_url[url]
        sub_uri = URI.parse(sub_url)
        next if sub_uri.host != uri.host
        queue.push( [sub_url, level - 1] )
        queued_url[url] = 1
      end
    end
  end
end


load_url(url)