SmartNewsのフィード配信を実装してみた


ニュースアプリに記事が載る仕組みは?

 SmartNewsやGunosyといったニュースアプリは毎日色々な記事を表示させています。それを実現しているのがフィード配信です。フィード配信とはサイトのURLに定期的にアクセスして新着記事を探し、それを別のサイトに投稿する仕組みを用いた配信になります。

 記事を配信したいサイトはニュースアプリ側の仕様に従った情報を渡してあげる必要があります。記事を配信したいサイトは情報を渡すためのURLをニュースアプリ側に伝え、ニュースアプリ側はそのURLに定期的にアクセスすることにより新規コンテンツのを自動的に探し出すことができます。

学んだことたち

XML, RSSとは

 XMLとはHTMLと同じくマークアップ言語の一つです。HTMLとの大きな違いとして、XMLでは自分でタグを自由に定義することができます。タグ自体に意味を持たせることができるので人間にとっては読みやすいかつ、機械にもタグの属性や重要度がわかりやすい言語です。

 RSSとは、記事などのコンテンツの情報を配信するための技術です。フィード配信に用いられており、RSSの他にもAtomもフィード配信に用いられています。

CDATAとは

 SmartNewsの仕様書を読んでいると記事情報などのタグ中で <![CDATA[]]> で囲まれている箇所がありました。CDATAってなんだと思って調べてみました。
 まずXMLで書かれたコードは構文解析がなされます。なので以下のような例では、<部長>という要素が含まれる<社員>という要素になります。


<社員>
 <部長>大原</部長>
</社員>

 しかしこのような構文解析をさせずに、ただ単に社員というタグの中に定義したタグや、pタグなどのhtmlを書きたい時はどうしたらいいのか。。その時に用いられるのがCDATAです。CDATAで囲まれた箇所は構文解析をされずにXMLパーサーを透過してくれます。

mime-typeの指定

 ニュースアプリ側はURLに定期的にアクセスして必要な情報を取得して、新着記事を探しています。そのため、仕様に則ったファイルを作成してそこにアクセスしてもらうという手段を考えました。この時に問題となったのがmime-typeの指定です。

 mime-typeとはファイルの種類を示すものです。ブラウザはHTTPヘッダーなどでファイルの種類が指定されていなければ、ファイルを拡張子で判断してcontent-typeを決めています。example.xmlというファイルであればmime-typeは text/xml と判断されてしまいます。

 SmartNewsのフィード配信で必要なmime-typeは application/xml+rss なのでを指定したい。。。そこで色々とXML上でmime-typeを指定する方法はないか調べたのですがなさそうでした。なので作成したファイルを S3 にあげて、フィードリーダーがURLにアクセスした時にダウンロードして、header情報でmime-typeを指定してあげることで解決しました。

media:thumbnailなどの拡張されたタグ

 まず、<media:thumbnail>ってなんだ。なんか仕様書に書かれている他のタグ<title>などと様子が違うことを感じ取りました。そこで調べてみました。

 まず、XMLやRSSはタグを自由に定義することができます。また、yahooやSmartNewsなどはタグを拡張して一般の人が使えるように公開してくれています。そのためタグ名がぶつかってしまうことが考えられます。そこでタグに対する一意性を確保する必要があります。その時にタグに対するnamespaceタグ名:で繋ぐことでタグの一意性を確保しています。

実装で困ったこと

 最初にchannnelのxmlを記述し、それをSimpleXMLElementクラスのオブジェクト化しました。そのオブジェクトにaddChildをすることによってitemのタグを作成していました。

 しかし、media:thumbnailタグを作成する時に問題が。titleと同様にaddChildをしてあげてもただのthumbnailタグが表示されてしまう。。この問題に関しては拡張されたタグということが関係していました。addChildで拡張されたタグを作成してあげる時には、第3引数にnamespaceを入れてあげることでmedia:thumbnailと正しくタグを生成してくれます。

 もう一つの問題が発覚しました。titleタグの時は<title>土佐日記</title>のように開きタグと閉じタグの間にデータを入れてあげたらよかったのに、media:thumbnailは<media:thumnail url="http://url">のようにタグ中のurl属性にデータを入れる必要がある。。まず、タグに属性を追加するにはaddAttribute関数を用います。第一引数に属性名、第二引数に属性に入れるデータを指定します。その次に、namespaceつきタグを読み込む方法についてです。children関数を使います。childrenメソッドでタグのprefixを指定して、suffixをアローで繋いであげることで読み込んでくれます。