Note: この記事は、3年以上前に書かれています。Webの進化は速い!情報の正確性は自己責任で判断してください。
または、如何にしてRSSからJSONを取得するか。ありふれたネタですが、久々にJS触って楽しかったので晒してみる。
自サイトのはてブ状況は、たとえば人気エントリーなんかで確認することができますが、よく見るとRSSも配信しています。このRSSをPerlなんかで引っ張ってくれば、自ドメインのJavaScriptで解析できるわけですが、どうせなんでJSONにしてみましょう。JSONの構造はJavascriptの連想配列と殆ど同じなので(実はまったく同じではない)、いったん取得してしまえば、XMLを解析するよりぐっと楽に操作できます。
Perlスクリプト —xml2json
#!/usr/local/bin/perluse strict;use warnings;use XML::Simple;use LWP::Simple;use JSON::Syck;my $xml = 'http://b.hatena.ne.jp/entrylist?sort=count&url=http%3A%2F%2Farchiva.jp%2F&mode=rss';my $filename = '/xxxxx/xxxxx.json';my $document = LWP::Simple::get($xml) or die "cannot get content from $xml";my $parser = XML::Simple->new;my $data = $parser->XMLin($document);my $json = JSON::Syck::Dump($data);open( FILE, "> $filename" ) or die "$! - $filename\n";print FILE $json;close( FILE );__END__
$xmlで指定したXML文書を元に、$filenameにJSON形式でファイルを出力します。こいつをCRON等で1日1回とか回しとけば良いでしょう。単に「print $json」して毎回呼んでも良いんですが、大して変化するわけじゃなし、書き出したファイル読む方が速い。
まあPipesとか使えばJSON出力できるようですし、必要ないっちゃないんですが、自前で用意してたほうが融通ききますしね。
use CGI;my $q = CGI->new;my $c = $q->param('callback');if ($c){print "$c($json)";}
とでも付け加えればJSONPになります。コールバック関数名で囲んでるだけですけどね。公開APIにするわけでもないので、今回は割愛。
XMLHttpRequest
var xhr = {create: function(){var req = window.XMLHttpRequest? new XMLHttpRequest(): (function(){try { return new ActiveXObject("Msxml2.XMLHTTP"); }catch(e) {try { return new ActiveXObject("Microsoft.XMLHTTP"); }catch(e) { return null; }}})();return req;},get: function(file,callback,type,async){var data;var req = xhr.create();async == 'false'? req.open("GET", file, false): req.open("GET", file, true);req.onreadystatechange = function() {if (req.readyState == 4 && req.status == 200) {type == 'xml'? data = req.responseXML: data = req.responseText;if (type == 'json'){// secuity caution!data = eval("(" + data + ")");}if (typeof callback == 'function'){callback(data);}}}req.send('');}}
今回のメイン。XHR処理は一度カプセル化しときたかったんですよね。目新しいとこは何もないですが。良いんだよ。俺のJSは基本趣味だし。サクっとテストするときには、これくらい手軽なパーツが欲しいんですよぅ。
xhr.get('./hateb.json', showjson, "text", "true");
...な感じで呼び出してやります。コールバック関数(showjson。後述)は別に用意しておく必要があります。無ければ何もしない。
showjson
var showjson = function(json){var data = JSON.parse(json);var targ = document.getElementById('contents');var text = '';for (var i=0; i < data.item.length; i++){if(data.item[i].link && data.item[i].title){var link = data.item[i].link;var title = data.item[i].title;title = title.replace('</.+>','');title = title.replace('<',"<");title = title.replace('>','>');title = title.replace(' - Archiva','');text += '<li><a href="' + link + '">'+ title+ '</a>'+ '<img src="http://b.hatena.ne.jp/entry/image/' + link + '" />'+ '</li>';}}text = '<ol>' + text + '</ol>';targ.innerHTML = text;}
随所に手抜きが見られます(ォィ)。良いんだよ、たかだか30件。ここは見れれば良いんだし。
「JSON.parse()」してる部分だけ注目。これはjson2.jsでパースしてます。JSONデータは「eval("(" + data + ")")」とでもしてやれば問題なく使えるんですが、中に妙な記述が混じっていると非常に危険なので、ちゃんとJSONなのか解析したほうがセキュリティ的に吉。今回のようなケースだと気にしなくても良いかもですが、まあサンプルということで。
Note: スパム対策が面倒なので、コメント投稿を廃止しました。以前のコメントは残します。
ご意見・ご要望はtwitter@sigwygかはてブコメントにて。