Rubyでどう書く?:重複したRSSをまとめる
「ネットの話題を追いかけるために、はてブのホッテントリや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 = []
4 rss_urls = []
5 title=""
6
7 ARGV.each do | rss_url |
8 open(rss_url) do | http |
9 response = http.read
10 rss_results = RSS::Parser.parse(response, false)
11
12 if rss_results && rss_results.channel && rss_results.channel.title
13 title += " と " if title.size > 0
14 title += rss_results.channel.title
15 end
16
17 rss_results.items.each do | item |
18 unless rss_urls.include? item.link
19 rss_urls << item.link
20 rss_feeds << item
21 end
22 end
23 end
24 end
25
26 rss = RSS::Maker.make("2.0") do | writer |
27 writer.channel.title = title || ""
28 writer.channel.link = rss_urls[0] || ""
29 writer.channel.description = title || ""
30 rss_feeds.each do | feed |
31 feed.setup_maker(writer)
32 end
33 end
34
35 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ブログなどで教えていただきたいと思います。
- コメント(2件)
#1 someeda
- 2008/06/27 00:15:08
#2 tomita
- 2008/06/30 12:50:21
- 特集: Rubyでどう書く? (7件)
- 今日のトップ記事
- 昨日
- 2日前
- 3日前
- 6日前
- 7日前
- ホワイトペーパー
- 話題のタグ
このアクセサリはiPhoneでは動作しません
iPhoneでコピー&ペーストを実現するオープンソースソリューションが登場
mixiサービス企画部長に聞く、「プラットフォームを開放する理由」
iPhone 3Gはメールにファイルを添付できないの?
発射台での度胸試し--J・L・ガセー氏が見た「MobileMe」の問題点
Firefox 3.1で強化されるHTML 5対応--Canvas Text APIを検証
つなげ! 速く、美しく、正確に--光ケーブル工事の技能を競う全国大会が開催
あなたのパワポ資料が近未来的に:MSがプラグイン公開
無料の「Oracle Database XE」で高速バッチ処理:活用のポイント
ZDNet Japan ホスティング特集
DELLが掲げる「新・仮想化アセスメントサービス」
セキュリティ対策レベルテスト公開!
Webセキュリティ特集
Techno Exchange
仮想化環境で求められるストレージの要件
ZDNet Japan Green IT
APC SOLUTIONS FORUM 2008をレポート