はてなブックマークRSS取得

Rubyの標準添付ライブラリRSSを用いて、はてなブックマークRSSから情報を取得するサンプルを作ってみました。

情報源: RSS Parser - COZMIXNG

RSSフィード取得

RSS::Parserから直接HTTPでRSSを取得することもできるようですが、実験段階で本物のはてなブックマークにリクエストが多発するのは避けたいので、まずはローカルにRSSフィードを保存します。

$ wget http://b.hatena.ne.jp/m-kawato/rss
$ mv rss rss.xml

RSSフィードのパーズ/アイテム取得

RSS:Parser.parseで、手元のRSSフィードをパーズし、その結果であるRSS::RDFオブジェクトのitemsオブジェクトで全アイテムを取得することができます。ここまではチュートリアルそのまま。

test1.rb:

require 'rss'

rss = RSS::Parser.parse('rss.xml')
p rss.class
p rss.items

実行結果:

$ test1.rb
RSS::RDF
[#<RSS::RDF::Item:0xb7c282e4 @trackback_about=[], @dc_rights=[], ...

アイテムからの情報取得

rss.xmlの中身を覗いてみると、itemの子要素として以下のXML要素が含まれていることが分かります。

  • title: 記事タイトル
  • link: 記事URL
  • description: コメント
  • dc:subject: タグ

これらの子要素は、それぞれ item.title, item.link, link.description, item.dc_subject というRubyメソッドを参照することができます。

test2.rb:

require 'rss'

rss = RSS::Parser.parse('rss.xml')
rss.items.each {|item|
  puts item.title
}

実行結果:

$ ruby test2.rb
私たちにもできる新型インフルエンザの身近な予防策〜国内で発生したら?〜 - 政府インターネットテレビ
PSJ渋谷研究所X: 新型インフルは、ほんとに難しい
TwitterまとめWiki
...

タグの取得

タグ (dc:subject) については、同一アイテム中に複数出現する場合があります。
これらの要素をまとめて取得する手段として item.dc_subjects のように複数形で呼び出せばよいのですが、この場合はdc:subject要素の中身ではなくて、dc:subject要素そのものが取り出されるようです。

test3.rb:

require 'rss'

rss = RSS::Parser.parse('rss.xml')
rss.items.each {|item|
  puts "-----"
  item.dc_subjects.each {|subject|
    puts subject.class
    puts subject
  }
}

実行結果:

-----
RSS::DublinCoreModel::DublinCoreSubject
<dc:subject>新型インフルエンザ</dc:subject>
-----
RSS::DublinCoreModel::DublinCoreSubject
<dc:subject>医療</dc:subject>
RSS::DublinCoreModel::DublinCoreSubject
<dc:subject>新型インフルエンザ</dc:subject>
-----
...

そこで、contentメソッドを呼び出してやることにって、dc:subject要素の中身を取り出すことができます。

test4.rb:

require 'rss'

rss = RSS::Parser.parse('rss.xml')
rss.items.each {|item|
  puts "-----"
  item.dc_subjects.each {|subject|
    puts subject.content.class
    puts subject.content
  }
}

実行結果:

$ ruby test4.rb
-----
String
新型インフルエンザ
-----
String
医療
String
新型インフルエンザ
-----
...

必要な情報をまとめて取り出す

以上を組み合わせて、RSSフィード中の各アイテムについて、タイトル、URL、コメント、タグの情報をまとめて取り出すためのRubyコードは以下のようになります。

test5.rb:

require 'rss'

rss = RSS::Parser.parse('rss.xml')
rss.items.each {|item|
  puts "title: #{item.title}"
  puts "url: #{item.link}"
  puts "tags: " + item.dc_subjects.map{|subject| "[#{subject.content}]"}.join
  puts "comment: #{item.description}"
  puts
}

実行結果:

title: 私たちにもできる新型インフルエンザの身近な予防策〜国内で発生したら?〜 - 政府インターネットテレビ
url: http://nettv.gov-online.go.jp/prg/prg2572.html
tags: [新型インフルエンザ]
comment:

title: PSJ渋谷研究所X: 新型インフルは、ほんとに難しい
url: http://shibuken.seesaa.net/article/119652110.html
tags: [医療][新型インフルエンザ]
comment:
...