【问题标题】:Mechanize - Simpliest way to check if page have been updated?Mechanize - 检查页面是否已更新的最简单方法?
【发布时间】:2011-10-01 21:04:49
【问题描述】:

使用 Mechanize 查看页面是否已更新的最简单的解决方案是什么?

我正在考虑创建一个名为 pages 的表。

那应该是:

pagename - varchar
page - text
pageupdated - boolean

我应该如何创建屏幕抓取并将数据保存在数据库中? 以及如何创建一种方法来将表中的 html 与抓取的数据进行比较。检查页面是否已更新。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 mechanize


    【解决方案1】:

    答案已更新和测试。

    这是一个使用 Page 模型(并使用 retryable-rb)的示例:

    rails 生成脚手架页面名称:string remote_url:string page:text digest:text 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
    

    我很确定这是一个不相关的问题,但是当我在rails console 和我的测试应用程序中尝试require 'mechanize' 时,我似乎遇到了LoadError。不确定是什么原因造成的,但当我能够成功测试此解决方案时,我会更新我的答案。

    确保您记得将其添加到您的应用程序的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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-07
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 2012-05-03
      • 2011-09-14
      • 2012-07-13
      相关资源
      最近更新 更多