RSS を YAML に変換する
ここまで学んだことの応用で、RSS をリモートから取得して YAML に変換してファイルに保存、というのをしたいです。
RSS2YAML というクラスを作って処理してみることにしました。
RSS2YAML.new('http://d.hatena.ne.jp/rubyo/rss').to_yaml
で RSS::RDF オブジェクトを YAML に変換したものが返ります。以下はこのクラスを使った yaml2rss.rb です。引数にフィードの URI を与えると、標準出力に YAML がはき出されます。
#!/usr/local/bin/ruby require 'open-uri' require 'rss/1.0' require 'yaml' class RSS2YAML def initialize(url) @url = url end def to_yaml rss = self.parse_rss(@url) rss.to_yaml if rss end def get_remote(url) begin return Kernel.open(@url).read rescue OpenURI::HTTPError return nil end end def parse_rss(url) content = self.get_remote(url) if content begin return RSS::Parser::parse(content) rescue RSS::InvalidRSSError return nil end end end public :to_yaml protected :get_remote, :parse_rss end if ARGV.size != 1 puts "Usage: ruby rss2yaml.rb <url>" exit end puts RSS2YAML.new(ARGV.shift).to_yaml
- 一応例外をキャッチするようにしてみました。クラス内部で例外が起こった場合に、それを補足して nil を返すというのは行儀という意味でどうなのでしょうか。こういう場合はどうするのがベストなのでしょう。
- get_remote や parse_rss はクラス内だけで利用するので protected にしてみました。
このスクリプトを実行して、
$ ruby rss2yaml.rb http://d.hatena.ne.jp/rubyo/rss > rss.yaml
とリダイレクトで保存したところ、うまく保存できました。
復元用のスクリプトも書いてみます。
#!/usr/local/bin/ruby require 'yaml' require 'rss/1.0' rss = YAML::load(ARGF.read) rss.items.each do |item| puts item.link end
ARGF を使ったフィルタにしてみました。
$ cat rss.yaml | ruby yaml2rss.rb http://d.hatena.ne.jp/rubyo/20060402#1143961325 http://d.hatena.ne.jp/rubyo/20060402#1143960117 nil
実行結果が正しくありません。途中で nil が返ってきています。なぜでしょうか...。
RSS を YAML に変換するにあたって、RSS::RDF オブジェクトを to_yaml しているので、復元されたものは RSS::RDF オブジェクトになります。本当は復元したものは単なるデータ構造でオブジェクトではない...というものにしたいところです。こういう場合は RSS::RDF オブジェクトから Hash などを作って to_yaml するのが一般的だったりするのでしょうか、まだよく分かっていません。