使用procs和块和/或动态方法干掉代码的最佳方法

时间:2014-08-18 17:31:27

标签: ruby

我正在编写一种解析网站的方法,每个“刮刀”都有自己的方式收集信息,但两种方法之间有很多共同的功能。

的差异:

  • 一名刮刀使用Nokogiri通过css选择器打开页面
  • 其他刮刀使用RSS Feed收集信息

相似点:

  • 每个scraper创建一个具有以下属性的“Event”对象:
    • 标题
    • 日期
    • 描述

如果对于Nokogiri刮刀,我们会这样做:

    event_selector = page.css(".div-class")

    event_selector.each_with_index do |event, index|
        date = Date.parse(event.text) #code I want to share
    end

对于RSS scraper,我们做这样的事情

    open(url) do |rss|
      feed = RSS::Parser.parse(rss)

      feed.items.each do |event|
        description = Sanitize.fragment(event.description)
        date = description[/\d{2}-\d{2}-20\d{2}/]
        date = Date.strptime(date, '%m-%d-%Y') #code I want to share
      end
    end

^^从描述中通过正则表达式获取日期,然后通过.strptime方法将其转换为Date对象

正如您所看到的,每个刮刀使用2种不同的方法调用/方式来查找日期。我怎样才能将这些信息抽象成一个类?

我在考虑这样的事情:

class scrape 

  attr_accessor :scrape_url, :title, :description, :date, :url

  def initialize(options = {})

  end

  def find_date(&block)
     # Process the block??
  end

然后在每个刮刀方法中执行类似

的操作
scrape = Scrape.new
date_proc = Proc.new {Date.parse(event.text)}
scrape.find_date(date_proc)

这是解决这个问题的正确方法吗?简而言之,我希望拥有两个网站解析器的通用功能,将所需的代码传递给“scrape”类的实例方法。我非常感谢您解决这种情况的任何提示。

编辑:如果我说我想找到一个事件的“日期”,或者我找到它的方式 - 行为 - 或者运行的特定代码,它可能更有意义。

2 个答案:

答案 0 :(得分:0)

您可以使用“事件”构建器。像这样:

class Event::Builder
  def date(raw)
    @date = Date.strptime(raw, '%m-%d-%Y')
  end

  # ... more setters (title, description) ...

  def build
    Event.new(date: @date, ... more arguments ..)
  end
end

然后,在刮刀内:

open(url) do |rss|
  builder = Event::Builder.new
  feed = RSS::Parser.parse(rss)

  feed.items.each do |event|
    description = Sanitize.fragment(event.description)
    date = description[/\d{2}-\d{2}-20\d{2}/]
    builder.date(date)

    # ... set other attributes ...

    event = builder.build
    # do something with the event ...
  end
end

答案 1 :(得分:0)

您应该查看StrategyTemplate模式。这些是根据某些状态或配置编写执行不同操作的代码的方法。基本上你要编写一个Scraper类,然后将它作为WebScraper和RssScraper子类。每个类都将从Scraper类继承所有常用功能,但只是在如何获取日期,描述等方面有所不同。