ランプの中身(Ruby on Railsのシステム開発)
ランプの中身(Ruby on Railsのシステム開発)では、株式会社ケイビーエムジェイのRuby on Railsエンジニアが蓄積したノウハウを公開しています。Ruby on Railに関する技術解説や実践的なノウハウなど、開発現場の技術に則したコンテンツを随時追加していきます。 初心者の方でもわかりやすい技術解説を心がけています。リクエスト、ご質問も受け付けいますので、お気軽にコメントを記述して下さい。

< Rubyでどう書く?:Rubyで特定UR... | メイン | Rubyでどう書く?:RubyでWord... >

ZDnetで連載Ruby記事
2008.06.25

Rubyでどう書く?:重複したRSSをまとめる

 KBMJがZDnetで連載している記事を紹介します。コメントなどありましたらそちらでお願いします。

Rubyでどう書く?:重複したRSSをまとめる 高瀬裕一(KBMJ)

「ネットの話題を追いかけるために、はてブのホッテントリやlivedoor クリップの人気ページをRSSで取得しています。でも、重複していることも多いんです。助けてください」(32才 男性・家事手伝い)――よろしい、ならばRubyで書こう。 

第4回目のテーマは「重複したRSSをまとめる」と題しまして、Rubyで複数のRSSから重複したエントリを除去する問題を出します。

問題

 最近、はてなブックマークやlivedoor クリップなど、ユーザーが外部のサイトを集めて、その結果を出力するサービスが増えてきました。

 ただ、一部のサイトを見ているだけで話題を追うことができるので便利なのですが、同じURLが複数のRSSにあり「もうこれは見たのに……」という事も多いですよね。

 そこで今回は、複数のRSSを一つのRSSとして出力するプログラムを問題にします。

仕様

  • RSSのURLは、コマンドラインから引数として1個以上与えられる。
  • 結合した結果のRSSのタイトルおよび説明は、各引数のタイトルをつなげたものとする。
  • 結合した結果のRSSのURLは第一引数のURLとする。
  • フィードのリンク先が同一のものを同じフィードとして扱う。
  • 出力順は第一引数のものを順に出力し、その後第二引数、第三引数のものを順に出力する(同じフィードとして扱うものは除外する)。
  • 重複したものは前の引数の内容を出力する。
  • 出力先は標準出力とする。
  • 出力するRSSのバージョンは2.0

回答例

 1 require 'rss'
 
2
 
3 rss_feeds = rss_urls = []
 
4 title=""
 
5
 
6 ARGV.each do | rss_url |
 
7   open(rss_url) do | http |
 
8     response = http.read
 
9     rss_results = RSS::Parser.parse(response, false)
 
10    
 
11     if rss_results && rss_results.channel && rss_results.channel.title
 
12       title += " と " if title.size > 0
 
13       title += rss_results.channel.title
 
14     end
 
15    
 
16     rss_results.items.each do | item |
 
17       unless rss_urls.include? item.link
 
18         rss_urls << item.link
 
19         rss_feeds << item
 
20       end
 
21     end
 
22   end
 
23 end
 
24
 
25 rss = RSS::Maker.make("2.0") do | writer |
 
26   writer.channel.title = title || ""
 
27   writer.channel.link = rss_urls[0] || ""
 
28   writer.channel.description = title || ""
 
29   rss_feeds.each do | feed |
 
30     feed.setup_maker(writer)
 
31   end
 
32 end
 
33
 
34 puts rss.to_s

 試しに、livedoor クリップ 人気ページと、はてなブックマーク 人気エントリーを取得してみましょう。

ruby rss.rb http://clip.livedoor.com/rss/hot http://b.hatena.ne.jp/hotentry?mode=rss

 本記事を執筆時点では、実行結果は以下のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
 
xmlns:content="http://purl.org/rss/1.0/modules/content/"
 
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
 
xmlns:dc="http://purl.org/dc/elements/1.1/"
 
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
 
<channel>
   
<title>livedoor クリップ - 人気ページ と はてなブックマーク 最近の人気エントリー</title>
   
<link>http://clip.livedoor.com/rss/hot</link>
   
<description>livedoor クリップ - 人気ページ と はてなブックマーク 最近の人気エントリー</description>
08-06-23 22:52 $ ruby "test.rb" "http://clip.livedoor.com/rss/hot" "http://b.hatena.ne.jp/hotentry?mode=rss" | head -20
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
 
xmlns:content="http://purl.org/rss/1.0/modules/content/"
 
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
 
xmlns:dc="http://purl.org/dc/elements/1.1/"
 
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
 
<channel>
   
<title>livedoor クリップ - 人気ページ と はてなブックマーク 最近の人気エントリー</title>
   
<link>http://clip.livedoor.com/rss/hot</link>
   
<description>livedoor クリップ - 人気ページ と はてなブックマーク 最近の人気エントリー</description>
   
<item>
     
<title>Engineer25 すべてを楽しむ若きスーパーエンジニア達 第4回 cho45氏- ウェブキャリア</title>
     
<link>http://www.web-career.com/contents/engineer25/4.html</link>
     
<description></description>
     
<dc:subject>interview</dc:subject>
     
<dc:subject>ruby</dc:subject>
     
<dc:subject>javascript</dc:subject>
     
<dc:subject>program</dc:subject>
   
</item>
   
<item>
   ...中略...
   
</item>
 
</channel>
</rss>

解説

 本サンプルプログラムは、大きく3段階の処理になっています。

 第1段階(6行目から9行目)では、渡された引数を元に各ページにアクセスし、RSSを解析しています。

 第2段階(11行目から20行目)では、rss_feeds内にRSSを分解したフィードの内容を登録しています。

 今回は第一引数の出力内容を優先するので、順番を管理しやすいArrayに登録しました。そして、重複チェック用に、rss_urlsというArrayを作って、登録時にそこにurlを入れ、urlが既に登録されていないかチェックをしています。

 第3段階目(25行目から34行目)では、全RSSの取得を完了した後で、makeでRSSを再生成して出力しています。

最後に――

 今回のお題は主に自分が必要と感じるものを作ってみました。

 パーサが標準のライブラリにあるので特に手間無く作れましたが、もうちょっと実用度を上げようとすると、サーバが落ちている場合や、引数が間違えている場合などの例外処理を組み込むのも良いと思います。

 こんな風に作ってみたよという方が居られましたら、コメントやbuilderブログなどで教えていただきたいと思います。

コメント (0)  |トラックバック (0)

ブックマークに追加する

トラックバック URL

この記事にコメントする

ニックネーム:
メールアドレス:
URL:


KBMJのWebソリューション
Ruby on Rails Summer Festival 2008開催決定!!

TOPICS

2008/08/14
ZD Net Builder」の連載記事です。第七回は「Rubyでどう書く?:RubyCocoa+Core Animationでお手軽アニメーション」が掲載されました。

2008/08/06
ZD Net Builder」の連載記事です。第六回は「Rubyでどう書く?特別編:Matzからのお題」が掲載されました。

2008/07/29
アットマーク・アイティ」にケータイWebアプリ開発、9つの注意点が掲載されました。

2008/07/11
ZD Net Builder」の連載記事です。第五回は「Rubyでどう書く?:RubyでWord文書を作成する」が掲載されました。

全体のRoR最新ブログ一覧

プロフィール

  • goto
  • 23 歳
  • 毎週KBMJでは、"ZDnet"にRubyの記事を連載しています。
    ここでは、その記事を紹介します。

ブログの購読

RSS

timelog
株式会社ケイビーエムジェイロゴ