LoginSignup
27
25

More than 5 years have passed since last update.

RSSを取得して自社サイトに埋め込みたい?それ、簡単ですよ。Railsならね。

Posted at

Hey Say、RSS使ってるかい?

普段、FeedlyとかFeedlyとかFeedlyとかでRSSを読んでいるエンジニア諸君、「自分でRSSリーダーを作ろうと思ったことはないかね?」。僕はありません。

でもお仕事でこういう内容を実装することはあると思います。

ということで本日は、Rails(Ruby)で使えるParserやらgemやらを通じてココらへんの処理について見ていきます。

そもそもRSSって一種類じゃないよね

僕らが普段何気に使っているRSS(ここでは広義にサイトの更新情報をフィードで提供するものとする)ですが、実はこれには規格が幾つか存在します。

  • RSS 1.0
  • RSS 2.0
  • Atom

RSSは他にもいくつか0.9x系も存在するみたいだけど、とりあえず上記の3つを抑えておけば問題ないと思われる。(多分ね

RSS1.0のサンプル

RDF Site Summary (RSS) 1.0 日本語訳より拝借。

実際に欲しいフィード情報は、rdf>item内に含まれている。実際に取れそうな情報は、titlelinkdescription辺りか。

<?xml version="1.0"?>

<rdf:RDF 
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
>

  <channel rdf:about="http://www.xml.com/xml/news.rss">
    <title>XML.com</title>
    <link>http://xml.com/pub</link>
    <description>
      XML.com features a rich mix of information and services 
      for the XML community.
    </description>

    <image rdf:resource="http://xml.com/universal/images/xml_tiny.gif" />

    <items>
      <rdf:Seq>
        <rdf:li resource="http://xml.com/pub/2000/08/09/xslt/xslt.html" />
        <rdf:li resource="http://xml.com/pub/2000/08/09/rdfdb/index.html" />
      </rdf:Seq>
    </items>

    <textinput rdf:resource="http://search.xml.com" />

  </channel>

  <image rdf:about="http://xml.com/universal/images/xml_tiny.gif">
    <title>XML.com</title>
    <link>http://www.xml.com</link>
    <url>http://xml.com/universal/images/xml_tiny.gif</url>
  </image>

  <item rdf:about="http://xml.com/pub/2000/08/09/xslt/xslt.html">
    <title>Processing Inclusions with XSLT</title>
    <link>http://xml.com/pub/2000/08/09/xslt/xslt.html</link>
    <description>
     Processing document inclusions with general XML tools can be 
     problematic. This article proposes a way of preserving inclusion 
     information through SAX-based processing.
    </description>
  </item>

  <item rdf:about="http://xml.com/pub/2000/08/09/rdfdb/index.html">
    <title>Putting RDF to Work</title>
    <link>http://xml.com/pub/2000/08/09/rdfdb/index.html</link>
    <description>
     Tool and API support for the Resource Description Framework 
     is slowly coming of age. Edd Dumbill takes a look at RDFDB, 
     one of the most exciting new RDF toolkits.
    </description>
  </item>

  <textinput rdf:about="http://search.xml.com">
    <title>Search XML.com</title>
    <description>Search XML.com's XML collection</description>
    <name>s</name>
    <link>http://search.xml.com</link>
  </textinput>

</rdf:RDF>

RSS2.0のサンプル

RSS 2.0 Specification 日本語訳より拝借。

こちらはrss>channel>item内に含まれてる。実際に取れそうな情報は、titlelinkdescriptionpubDateあたり。

<?xml version="1.0"?>
<rss version="2.0">
   <channel>
      <title>Liftoff News</title>
      <link>http://liftoff.msfc.nasa.gov/</link>
      <description>Liftoff to Space Exploration.</description>
      <language>en-us</language>
      <pubDate>Tue, 10 Jun 2003 04:00:00 GMT</pubDate>
      <lastBuildDate>Tue, 10 Jun 2003 09:41:01 GMT</lastBuildDate>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs>
      <generator>Weblog Editor 2.0</generator>
      <managingEditor>editor@example.com</managingEditor>
      <webMaster>webmaster@example.com</webMaster>
      <item>
         <title>Star City</title>
         <link>http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp</link>
         <description>How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia's &lt;a href="http://howe.iki.rssi.ru/GCTC/gctc_e.htm"&gt;Star City&lt;/a&gt;.</description>
         <pubDate>Tue, 03 Jun 2003 09:39:21 GMT</pubDate>
         <guid>http://liftoff.msfc.nasa.gov/2003/06/03.html#item573</guid>
      </item>
      <item>
         <description>Sky watchers in Europe, Asia, and parts of Alaska and Canada will experience a &lt;a href="http://science.nasa.gov/headlines/y2003/30may_solareclipse.htm"&gt;partial eclipse of the Sun&lt;/a&gt; on Saturday, May 31st.</description>
         <pubDate>Fri, 30 May 2003 11:06:42 GMT</pubDate>
         <guid>http://liftoff.msfc.nasa.gov/2003/05/30.html#item572</guid>
      </item>
      <item>
         <title>The Engine That Does More</title>
         <link>http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp</link>
         <description>Before man travels to Mars, NASA hopes to design new engines that will let us fly through the Solar System more quickly.  The proposed VASIMR engine would do that.</description>
         <pubDate>Tue, 27 May 2003 08:37:32 GMT</pubDate>
         <guid>http://liftoff.msfc.nasa.gov/2003/05/27.html#item571</guid>
      </item>
      <item>
         <title>Astronauts' Dirty Laundry</title>
         <link>http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp</link>
         <description>Compared to earlier spacecraft, the International Space Station has many luxuries, but laundry facilities are not one of them.  Instead, astronauts have other options.</description>
         <pubDate>Tue, 20 May 2003 08:56:02 GMT</pubDate>
         <guid>http://liftoff.msfc.nasa.gov/2003/05/20.html#item570</guid>
      </item>
   </channel>
</rss>

Atomのサンプル

RFC 4287 The Atom Syndication Format 日本語訳より拝借。

こちらはfeed>entry内に含まれてる。実際に取れそうな情報は、titlelinksummaryupdatedあたり。

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Example Feed</title>
  <link href="http://example.org/"/>
  <updated>2003-12-13T18:30:02Z</updated>
  <author>
    <name>John Doe</name>
  </author>
  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>

  <entry>
    <title>Atom-Powered Robots Run Amok</title>
    <link href="http://example.org/2003/12/13/atom03"/>
    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
    <updated>2003-12-13T18:30:02Z</updated>
    <summary>Some text.</summary>
  </entry>

</feed>

それぞれ構造、使えそうな情報に差があるようだ。

実データを見てみる

ちょうどいいことに、技術評論社が3パターンでの配信を行っているので、確認してみる。

RSS1.0

RSS2.0

Atom

まぁ大体上記のサンプルと同等の構造をとってますね。ここまではわかった。じゃあ本題に移ろう。

取得してパースしてみる

今回の目的は、「サクッとRSS(Atom)をパースする」ことである。便利なことに、to_feedで好きなfeedに変換でき(そうな)メソッドが定義されているようで、RSS1.0でもRSS2.0でもAtomでも、なんでもかんでもいい感じによろしくしてくれそうである。

ものは試しに、こんな感じのコードを走らせてみる。

require 'rss'

sites = [
    "http://gihyo.jp/feed/rss1",
    "http://gihyo.jp/feed/rss2",
    "http://gihyo.jp/feed/atom"
]

sites.each do |site|
    rss = RSS::Parser.parse(site, false).to_feed('atom1.0')
    rss.items.each do |item|
        puts item.title
        puts item.link
        puts item.description
        puts
    end
end

ダメだった。

やっぱり定義されてないタグがあると、怒られるようだ。to_feedの意味よ。

自前で各仕様ごとにパラメータを分けた処理を書いてもいいのだが、やっぱり凡人の僕は楽をしたいもんである。車輪の再発明はしたくない。

gemを試してみる

世の中そううまくはいかないことがわかったので、今度はgemを頼ってみる。

Ruby ToolboxとGoogle先生の情報を頼りに、feedjira/feedjiraが良さそうだったので、試してみる。

gemを入れて、

gem 'feedjira'

ざっくりこんな感じで書いてみる。ソースが汚いのはご愛嬌。

sites = [
    "http://gihyo.jp/feed/rss1",
    "http://gihyo.jp/feed/rss2",
    "http://gihyo.jp/feed/atom"
]

@list = []
sites.each do |site|
  rss = Feedjira::Feed.fetch_and_parse site
  rss.entries.each do |item|
    @list += [:title => item.title,
              :url => item.url,
              :summary => item.summary,
              :published => item.published.to_time.strftime("%Y-%m-%d %H:%M:%S")]
  end
end
@list

出力はこうなる。

[60]
0:  {
    "title": "第440回 LibreOffice Writerの日本語レイアウト ── Ubuntu Weekly Recipe"
    "url": "http://gihyo.jp/admin/serial/01/ubuntu-recipe/0440"
    "summary": "今回は,LibreOffice Writerを日本語ワードプロセッサとして使用する場合に,知っておきたい日本語レイアウトの設定について解説します。"
    "published": "2016-10-05 10:36:00"
    }-
1:  {
    "title": "第2回 トラブルに備える ── Javaでなぜ問題が起きるのか 〜システムをきちんと運用するための基礎知識"
    "url": "http://gihyo.jp/dev/serial/01/java-system-operation/0002"
    "summary": "本連載のテーマである「運用」は,システムがリリースしてからおこなわれるものです。では,開発者には運用の知識は必要ないでしょうか?"
    "published": "2016-10-05 10:20:00"
    }-
2:  {
    "title": "2016年10月5日 「最初の設計がダメすぎる」― systemdをめぐる終わりなき論争 ── Linux Daily Topics"
    "url": "http://gihyo.jp/admin/clip/01/linux_dt/201610/05"
    "summary": "Fedora,Ubuntu,Debianなど,いまやほとんどのメジャーなLinuxディストリビューションではsystemdが最初の起動処理システムとして採用されている。"
    "published": "2016-10-05 09:30:00"
    }-
(以下略)

RSS1.0、RSS2.0、Atom、同じプロパティ名で取得できました!

ソースを見ると、いい感じにラップしてくれていて、同じプロパティ名で取得できるようにしてくれているようです。これこれ、こういうのを待っていました。

表示だけならリアルタイムで出せばいいし、アプリ側に保存したいならfind_or_create_byみたいなんをいい感じに使えばいいんじゃないかな(まだ考えきれてない。

ご意見ご要望承ります。

27
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
25