サイト更新チェッカークラスのプロトタイプ
self.site_url にチェックしたい URL を設定し、
self.prepare で前処理をし(今は何もしていない)、
self.process で BODY 部から正規表現でデータを抽出し、
self.after で抽出したデータを加工(スペースを消したり)する、といったクラスをUpdateChecker::Base のサブクラスで定義する。
self.fetch で上記の定義どおりに処理をして、データを抽出するようになっている。
self.save は今のところは CSV で保存するようにしている。
とりあえず今のところはこんな感じなんだけれど、いろいろと足りない。
一つのまとまったものになるのは、もう少し先になりそうだ。
#!/usr/bin/ruby require 'open-uri' require 'rubygems' require 'fastercsv' class UpdateChecker class Base @@instances = {} def self.site_url=(url) @@instances[self] = {} unless @@instances.key?(self) @@instances[self][:site_url] = url end def self.prepare(&block) @@instances[self] = {} unless @@instances.key?(self) @@instances[self][:prepare] = block end def self.process(&block) @@instances[self] = {} unless @@instances.key?(self) @@instances[self][:process] = block end def self.fetch return [] unless @@instances.key?(self) contents = '' begin open(@@instances[self][:site_url]) do |http| contents = http.read end rescue Exception => e # TODO: OpenURI::HTTPError puts "#{@@instances[self][:site_url]} ... #{e.message}" end records = Extract.scan(contents, &@@instances[self][:process]) @@instances[self][:records] = records.map do |entry| @@instances[self][:after].call(entry) entry end self end def self.after(&block) @@instances[self] = {} unless @@instances.key?(self) @@instances[self][:after] = block end def self.save(filename) return false unless @@instances.key?(self) FasterCSV.open(filename, "w") do |csv| @@instances[self][:records].each do |entry| puts entry csv << entry.values end end true end end class Extract attr_accessor :records, :fields def initialize(source) @source = source @records = [] @fields = {} end def self.scan(source, &block) extract = self.new(source) begin # TODO: while 1 extract.fields = {} extract.instance_eval(&block) break if extract.fields.empty? extract.records << extract.fields end rescue Exception => e puts e end extract.records end def method_missing(name, *argv) # TODO: reg = argv[0] + '(.*)' val, @source = %r{#{reg}}m.match(@source).to_a.values_at(1, 2) @fields[name] = val unless val.nil? end end end class Onsen < UpdateChecker::Base self.site_url = 'http://localhost/feed/onsen.html' process do title '<td width="135">(.+?)<\/td>' link '(http://[^\s]+?asx)' end after do |entry| entry[:title] = entry[:title].gsub(/<[^<>]*>/m, '').strip end end p onsen = Onsen.fetch onsen.save('onsen.csv')