Механизация - самый простой способ проверить, обновилась ли страница? - PullRequest
2 голосов
/ 02 октября 2011

Какое самое простое решение с Mechanize, чтобы увидеть, была ли страница обновлена?

Я думал о создании таблицы с именем pages.

Это будет иметь:

pagename - varchar
page - text
pageupdated - boolean

Как создать скребок для экрана и сохранить данные в базе данных? И как создать метод для сравнения HTML в таблице с очищенными данными. Чтобы проверить, была ли страница обновлена.

1 Ответ

1 голос
/ 02 октября 2011

Ответ обновлен и проверен.

Вот пример использования модели страницы (и использования retryable-rb ):

рельсы генерируют каркасИмя страницы: строка remote_url: строковая страница: текстовый дайджест: текст page_updated: boolean

####### app/models/page.rb

require 'digest'
require 'retryable'

class Page < ActiveRecord::Base
  include Retryable

  # Scrape page before validation
  before_validation :scrape_content, :if => :remote_url?

  # Will cause save to fail if page could not be retrieved
  validates_presence_of :page, :if => :remote_url?, :message => "URL provided is invalid or inaccessible."

  # Update digest if/when all validations have passed
  before_save :set_digest

  # ...

  def update_page!
    self.scrape_content
    self.set_digest
    self.save!
  end

  def page_updated?
    self.page_updated
  end

  protected

  def scrape_content
    ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X) ' + 
         'AppleWebKit/535.1 (KHTML, like Gecko) ' + 
         'Chrome/14.0.835.186 Safari/535.1'

    # Using retryable, create scraper and get page
    scraper = Mechanize.new{ |i| i.user_agent = ua }
    scraped_page = retryable(:times => 3, :sleep => false) do
      scraper.get(URI.encode(self.remote_url))
    end
    self.page_updated = false
    self.page = scraped_page.content
    self.name ||= scraped_page.title
    self.digest ||= Digest.hexencode(self.page)
  end

  def set_digest
    # Create new digest of page content
    new_digest = Digest.hexencode(self.page)

    # If digest has changed, update digest and set flag
    if (new_digest != self.digest) && !self.digest.nil?
      self.digest = new_digest
      self.page_updated = true
    else
      self.page_updated = false
    end

    true
  end

end

Я вполне уверен, что это не связано, но мне кажется, что LoadErrorпытаюсь require 'mechanize' в rails console и моем тестовом приложении.Не знаю, с чем это связано, но я обновлю свой ответ, когда смогу успешно протестировать это решение.

Убедитесь, что вы не забыли добавить это в Gemfile:

вашего приложения.
gem 'mechanize', '2.0.1'
gem 'retryable-rb', '1.1.0'

Пример использования :

p = Page.new(:remote_url => 'http://rubyonrails.org/')
p.save!
p.page_updated? # => false, since page hasn't been updated since creation
p.remote_url = 'http://www.google.com/' # for the sake of example
p.update_page!
p.page_updated? # => true
...