第3章 応用・JavaScript関連技術

外部サイトのRSSを取得する

RSS(RDF Site Summary)概要

RSSは、ニュースやブログサイトなどのヘッドライン情報(タイトルや要約)を効率的に配信するために開発された文書フォーマットです。ドキュメントの見出しやリンクなどのリストを共通の書式で記述するために特化されているので、サイトの目次や更新情報などを効率的に配信することができます。既にニュースやウェブログのヘッドライン配信で多く利用され、標準的配信方法としての地位を確立しています。RSSは書式の規格なので、扱うコンテンツは何でもよく、個人的なブログやレビューなどもなんの問題もなくRSSとして扱えます。

RSSの活用方法

RSSはXMLで記述します。例えば、WordPressが自動出力するブログのRSSは下記のようなものになります。

SMARTで配信しているRSSの一部抜粋
<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SMART プログラミングとサイト構築のウェブマガジン</title>
	<atom:link href="https://rfs.jp/feed" rel="self" type="application/rss+xml" />
	<link>https://rfs.jp</link>
	<description>プログラミングとサイト構築の情報が集まるウェブマガジン &#34;SMART&#34;</description>
	<lastBuildDate>Sun, 11 Nov 2018 00:17:48 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.9.8</generator>
	<atom:link rel='hub' href='https://rfs.jp/?pushpress=hub'/>
	<item>
		<title>The Internet - Come Over</title>
		<link>https://rfs.jp/blog/music/the-internet-come-over.html</link>
		<comments>https://rfs.jp/blog/music/the-internet-come-over.html#respond</comments>
		<pubDate>Sun, 11 Nov 2018 00:17:48 +0000</pubDate>
		<dc:creator><![CDATA[リズムファクトリー]]></dc:creator>
				<category><![CDATA[MUSIC]]></category>

		<guid isPermaLink="false">https://rfs.jp/?p=5283</guid>
		<description><![CDATA[]]></description>
		<wfw:commentRss>https://rfs.jp/blog/music/the-internet-come-over.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
	</item>

上記のような、ドキュメント内容の要約や更新情報が掲載されたXMLファイルをRSSフィードと呼びます。

外部サイトのニュース見出しとリンクを利用する

RSSを公開しているサイトがあれば、そのリソースを使って自分のホームページに埋め込むことができます。
一般的な方法としては、cronのようなコマンドを利用して、RSSフィードを読みにいくスクリプトを定期的に実行し、その内容を自分のホームページに埋め込みます。このような方法により、自分のホームページのニュース欄が自動的に更新されるようになります。

RSSを利用するまでの流れ

RSSとして記述された情報は、容易に他のサイトからも利用することができます。どこかのサイトで、ブログや、天気予報、ニュースなどのコンテンツがRSSで記述されていれば、それを自分のサイトに自動的に埋め込むことができます。提供する側の利点としては、ニュースや天候予報などの情報を他サイトに流すことになりますが、ニュースの件名などに貼るリンク先を自サイトのURLにしておくことができるので、結果的にトラフィックを増やすことになります。

ソース提供サイトがRSSを提供するまでの流れと、利用ユーザがRSSを自サイトに取り込むまでの流れは以下のとおりです。

ソース提供サイトの作業の流れ
  1. 既存の情報をRSSフィードとして作成
  2. 利用ユーザにRSSフィードのURLを告知
利用ユーザが RSSを自サイトに埋め込むまでの作業の流れ
  1. ソース提供サイトにあるRSSフィードを取得
  2. 取得したデータを、HTMLなどに変換して出力

RSSフィードの読み込み

RSSが外部サイトの場合、JavaScriptはクロスドメインの制約によってそのRSSを取得することができません。例えば、A.jpとB.jpという2つの異なるドメイン間では、Ajaxを使った通信ができません。A.jpのページから、JavaScriptを使ってB.jpに接続すると、Webブラウザがエラーや警告を表示して接続をブロックします。これが、クロスドメインの制約です。

クロスドメインの制約はJavaScriptのようなプログラムを対象とするので、画像ファイルなどは外部サイトにあっても問題なく表示することができます。ちなみに、このクロスドメインの制約はWebブラウザに実装されているものです。HTTPプロトコル自体にはそのような制約がなく、ブラウザを介さないようなアプリやCGIなどはクロスドメインの制約を受けません。たとえば、A.jpにあるPHPから、B.jpに接続してRSSを取得するのはなんの問題もありません。

クロスドメインの制約を回避するには、いくつかの方法があります。下記の方法はいずれもRSSを配信しているサーバ側での対応が必要です。

  • HTML5のpostMessageを使ったクロスドキュメントメッセージング
  • HTML5のCORS(Cross-Origin Resource Sharing)
  • JSONP

RSS配信サーバがクロスドメイン対応されていない場合、上記の方法は使えず、JavaScriptのみでは解決しません。このような場合、RSSの取得はクロスドメインの制約を受けないサーバサイドのプログラムを使うのが簡単です(ここでのサーバは、RSSを配信するサーバではなく、HTMLやJavaScriptが置かれるサーバです)。HTMLに出力する部分はJavaScriptを使います。

サーバサイドのプログラムは何でも良いですが、今回はPHPを使います。
次のPHPは、取得したRSSをHTMLに変換して出力します。

output_rss.php
<?php
// タイムゾーンを日本に設定
date_default_timezone_set('Asia/Tokyo');

// 取得したいRSSのURLを設定
$url = "https://news.yahoo.co.jp/pickup/rss.xml";
// MAXの表示件数を設定
$max = 5;

// simplexml_load_file()でRSSをパースしてオブジェクトを取得、オブジェクトが空でなければブロック内を処理
if( $rss = simplexml_load_file( $url ) ){
	$cnt = 0;
	$output = '';
	/*
	* $item->title:タイトル
	* $item->link:リンク
	* strtotime( $item->pubDate ):更新日時のUNIX TIMESTAMP
	* $item->description:詳細
	*/
	// item毎に処理
	foreach( $rss->channel->item as $item ){
		// MAXの表示件数を超えたら終了
		if( $cnt >= $max ) break;

		// 日付の表記の設定
		$date = date( 'Y年m月d', strtotime( $item->pubDate ) );
		// 出力する文字列を用意
		$output .= '<a href="'. $item->link .'">' . $date . " " . $item->title . '</a><br>';
		$cnt++;
	}
	// 文字列を出力
	echo $output;
}

このPHPはHTMLやJavaScriptと同じ階層にあるとします。HTML側は、JavaScriptを使ってPHPが出力する値を受け取り、その値を要素に追加します。

index.html
<!DOCTYPE html>
<html lang="ja">
<body>

<script>
// HTMLドキュメントの解析後に実行
window.addEventListener('DOMContentLoaded', function() {
	// XMLHttpRequestのインスタンスを作成
	var req = new XMLHttpRequest();

	// 読み込み時の処理を設定
	req.onreadystatechange = function() {
		// readyState=4は全てのデータを受信済み、
		// status=200は正常に処理されたことを意味します
		if( req.readyState == 4 && req.status == 200 ) {
			// 結果を代入
			document.getElementById( "message" ).innerHTML = req.responseText;
		}
	}

	// 接続先のURLやメソッドを設定します
	req.open( "GET", "output_rss.php" );

	// リクエストをサーバに送信
	req.send();

})
</script>

<div id="message"></div>
</body>
</html>

これでRSSを取得し、HTMLに出力することができました。これでも良いのですが、毎回外部サーバからRSSを取得するのは処理速度の面であまり好ましいことではありません。定期的にRSSを取得し、ローカルにキャッシュを用意したほうがさらに良いでしょう。

定期的に巡回する方法

ニュースなどのRSSは1日に1回、多ければ数回更新されます。これを自動で定期的に読み込み、データを同期するにはcrontabというシェルコマンドを使います。
crontabの書式は下記のとおりで、分・時・日・曜日とコマンドのパスを記入します。

min hour day month week command

分・時・日・曜日の代わりにワイルドカード( * )を使うことができます。たとえば、毎日 10:00 にoutput_rss.phpを実行したい場合は、下記のように日・曜日にワイルドカードを使います。

10 0 * * * output_rss.php

毎月1日の10:00にoutput_rss.cgiを実行するには、下記のように記述します。

10 0 1 * * output_rss.php

それでは、crontabを実行して、定期実行の設定を行いましょう。cronファイルを編集するには、crontabにオプションの -e をつけて実行します。

crontab -e

編集画面で、たとえば以下のように入力します。

0 0 * * * /home/www/cgi-bin/output_rss.php

上記の意味は、「毎日0時0分にoutput_rss.phpを実行」となります。crontabに登録したら、先程のプログラムとHTMLを少し変更します。PHPはRSSをそのまま出力するのではなく、一度ローカルファイルとしてRSSを出力します。具体的には、output_rss.phpの下記のコード部分を、

echo $output;

次のように変更します。

// ファイル出力
file_put_contents ( "rss.xml" , $output );

このoutput_rss.phpが実行され、ファイルの作成が成功したら、HTMLはローカルにあるrss.xmlを取得すれば良いことになります。先程のindex.htmlの下記の部分を、

req.open( "GET", "output_rss.php" );

次のように変更します。

req.open( "GET", "rss.xml" );

これで余計なサーバ間の通信とRSSのパース処理が省かれ、処理速度が向上します。

RSSに関連した情報

ヘッドラインビューアソフトでのニュース収集

RSSフィードを表示するための、 RSSリーダーと呼ばれるサービス・アプリがあります。これらのサービス・アプリは、RSSを公開しているサイトを巡回し、そのヘッドライン一覧を表示するものです。

RSSリーダーとして有名なサービスはinoreaderやfeedly(英語)です。どちらのサービスにもiPhoneやAndroidアプリも用意されているので、興味のある記事を一括管理することができます。

RSSの歴史

RSSはもともと、Netscape Communications社がMy Netscapeポータルページにニュースヘッドラインを配信する方法として、1999年3月に開発・公開した規格です。
最初のRSS(RSS0.9)はRDFという規格をベースに、見出し一覧を配信するためのRDFコンパクト版のようなものでした。1999年7月には、見出しだけでなく、要約、著作権、更新日付などさまざまな情報も加えたサイトサマリーを提供できるようにしたRSS0.91が登場します。

RSSが多くのウェブサイトで利用されるようになると、これに独自の改造を加えたRSSなども出現し、多くの亜種が混在する危険性が高まりました。そのような事態を避けるために、基本的なサマリー提供機能をコアなRSSとして定義し、 より高度な機能はモジュールとして追加できるようにするという規格が開発者のグループで検討されました。この成果として2000年12月に提案されたのがRSS1.0です。

用語
RDF(Resource Description Framework)
RDF(Resource Description Framework) は、メタデータのプロパティを定義し、異なるアプリケーション同士がウェブを通じて効果的なデータ交換を可能にするためのメタデータフレームワークです。交換構文としてXMLを使用します。
XML(eXtensible Markup Language)
HTMLのようなシンプルなフォーマットで文書構造を記述でき、独自にタグを定義できることが特徴のマークアップ言語です。XML 準化は、W3Cで行なわれています。

関連記事