jQuery を使って各 SBM サービスからのブクマ数を取得して表示してみた

Category : jQuery

jQuery で任意のページの被ブックマーク数を各ソーシャルブックマークから取得したいと思ったので、勉強だと思ってやってみたよ。
とりあえず、はてな、Delicious、Livedoor クリップ、Buzzurl はできました。@nifty もできました。
おまけで、Twitter の投稿からのリンク数を取得するのに Topsy の API を使ってやってみました。

以下のような HTML で、ブックマークするボタンの直後に登録者数を表示して、各サービスごとのブックマークの数え方(○○usersって出るやつ)を単数形と複数形で分けたい。

<ul>
	<li><a href="登録リンク" id="addHatena">はてなアイコン</a></li>
	<li><a href="登録リンク" id="addDelicious">Deliciousアイコン</a></li>
	<li><a href="登録リンク" id="addLivedoor">Livedoorクリップアイコン</a></li>
	<li><a href="登録リンク" id="addBuzzurl">Buzzurlアイコン</a></li>
	<li><a href="登録リンク" id="addNifty">@niftyクリップアイコン</a></li>
	<li><a href="投稿リンク" id="postTwitter">Twitterアイコン</a></li>
</ul>

はてなブックマーク

はてなブックマーク数を取得して、エントリーページへのリンクと共に表示。
はてなはブックマーク数のみを取得できる API を公開しているのでそれを使いました。

jQuery(function ($) {

	var baseurl = location.href;

	function hatenaCount(data) {
		if (data > 0) {
			var user = (data === 1) ? ' user' : ' users';
			var link = '<a href="http://b.hatena.ne.jp/entry/' + baseurl + '">' + data + user + '</a>';
			$('#addHatena').after(link);
		}
	}

	$.getJSON('http://api.b.st-hatena.com/entry.count?url=' + encodeURIComponent(baseurl) + '&callback=?', hatenaCount);

});

まず、変数 baseurl に現在の URL を代入。
次にコールバック関数 hatenaCount を。
この API ではブックマークされていない場合は 0 が返ってくるので、値が 0 より大きい場合にのみ、カウントとリンクを表示するようにしました。
変数 user では、条件演算子を使って値が 1 であるかどうかを判定。true なら user を、false なら users を代入します。
変数 link で、a 要素を作って、after メソッドで a#addHatena の直後に追加しています。
値は $.getJSON で取得しました。コールバック関数が ? になっているのは、こうしておけば jQuery がやってくれるから……。

たぶん、一番簡単。

Delicious

Delicious はちょっと面倒。
最初に URL を md5 エンコードしないといけないらしいです。
今回は jQuery を使っているので、jQuery のプラグイン jQuery MD5 hash algorithm function を使いました。他にも md5 エンコードしてくれるライブラリは md5.js とかありますね。

jQuery(function ($) {

	var baseurl = location.href;
	var md5hash = $.md5(baseurl); //ここでプラグインを使っています

	function deliciousCount(data) {
		if (data.length > 0) {
			var count = data[0].total_posts;
			var user = (count === 1) ? ' person' : ' people';
			var link = '<a href="http://delicious.com/url/' + md5hash + '">' + count + user + '</a>';
			$('#addDelicious').after(link);
		}
	}

	$.ajax({
		type: 'GET',
		dataType: 'jsonp',
		url: 'http://feeds.delicious.com/v2/json/urlinfo/' + md5hash,
		success: deliciousCount
	});

});

$.getJSON で上手くできなかったので、$.ajax でやりました。
基本的には、はてなのと一緒ですね。
違うのは、person / people と、返ってくるもの。

ブックマークされていないページだと空のデータが返ってきて、data[0].total_posts > 0 だとエラーになるので、data.length > 0 でデータの文字数が 0 より大きい場合にのみ表示、という形にしました。
取得できる JSONP は、たとえば http://www.google.co.jp/ だとこういうのになります。

([{
	"hash":"9d0f4061beb6ae41f64eb124665e0768",
	"title":"Google",
	"url":"http:\/\/www.google.co.jp\/",
	"total_posts":1174,
	"top_tags":{
		"google":368,
		"search":318,
		"\u691c\u7d22":139,
		......
	}
}])

配列になっているのでそのように。
total_posts の値がブックマーク数です。
あとははてなのと一緒。

これが一番大変でした。

Livedoor クリップ

はてなのをちょっと変更するだけ。

jQuery(function ($) {

	var baseurl = location.href;

		function livedoorCount(data) {
		var count = data.total_clip_count;
		if(count > 0){
			var user = (count === 1) ? ' user' : ' users';
			var link = '<a href="http://clip.livedoor.com/page/' + baseurl + '">' + count + user +'</a>';
			$('#addLivedoor').after(link);
		}
	}

	$.getJSON('http://api.clip.livedoor.com/json/comments?link=' + encodeURIComponent(baseurl) + '&callback=?', livedoorCount);

});

取得できるのはこれ。同じく google.co.jp ですね。

({
	"link":"http://www.google.co.jp/",
	"Comments":[
		{
			//ユーザーのブックマーク情報
		},
		{
		......
		}
	],
	"public_clip_count":381,
	"last_clipped_on":1264610012,
	"StatusCode":200,
	"total_clip_count":436,
	"isSuccess":1,
	"Message":"comment list",
	"created_on":1151397785,
	"title":"Google"
});

total_clip_count がブックマーク数。
ユーザー情報までついてくるからちょっと容量が大きいです。
今回、google.co.jp の情報を取ってみたら、livedoor だけ 2.5KB もありました。他は大きくても 300B 程度。

Buzzurl

こっちも似たようのでいけました。

jQuery(function ($) {

	var baseurl = location.href;

	function buzzurlCount(data) {
		if (data.length > 0) {
			var link = '<a href="http://buzzurl.jp/entry/' + baseurl + '">' + data[0].users + ' USER</a>';
			$('#addBuzzurl').after(link);
		}
	}

	$.getJSON('http://api.buzzurl.jp/api/counter/v1/json?url=' + encodeURIComponent(baseurl) + '&cb=?', buzzurlCount);

});

まず、これも Delicious と同じように配列になっていて、ブックマークされていないと空のデータが返ってくるので、同じように data.length > 0 で中身がある場合に絞ります。
また、このサービスはブックマークしている人が複数人いても ○○USER と表示しているので、その区別をしなくてもいいです。なので、いったん変数に代入することなく、そのまま使うことにしました。
画像で取得すると複数形があるみたいですが、そっちが好みなら他のと同じように条件分岐で。
他に気をつけるのはコールバックが &callback= じゃなくて &cb= なことくらいですかね。

取得できるのはこれ。

([{
	"url":"http://www.google.co.jp/",
	"users":"121",
	"title":"Google"
}]);

ブックマーク数は users の値。
すごく分かりやすい。ファイルサイズも数字のみのはてなの次に小さいです。

@nifty クリップ

monmonさんのコメントを参考に書いたらちゃんとできました。アドバイスありがとうございました!
上手くいかなかった原因は、xml を $.ajax で取ろうとしていたからでした。別ドメインなのに……。

ちゃんと動いたコードはこれ。

jQuery(function ($) {
	var baseurl = location.href;

	function niftyCount(data) {

		if (data.status.code !== '200') return; //200じゃなければ終了

		var count = data.result.clips[0].count;
		if (count > 0) {
			var user = (count === 1) ? ' user' : ' users';
			var link = '<a href="http://clip.nifty.com/entry/?url=' + baseurl + '">' + count + user + '</a>';
			$('#addNifty').after(link);
		}
	}

	$.getJSON('http://api.clip.nifty.com/api/v1/counter?alt=json-in-script&url=' + encodeURIComponent(baseurl) + '&callback=?', niftyCount);

});

@nifty の API が返す JSON に入っているステータスコードが 200 でなければ、その時点で終了。他には 400, 403, 404, 503 を返すようです。
残りの部分はほとんど他と一緒。
エントリーページへのリンクは api.clip.nifty.com/api/v1/entry で取れるけど、http://clip.nifty.com/entry/?url=(URL) でも行けるようなので、データの容量も考慮した結果、こっちを使うことにしました。

取得できるのはこれ。

({
	"status": { 
		"code": "200",
		"message": "OK",
		"language": "ja"
	},
	"result": {
		"clips": [{
			"url": "http\u003a\u002f\u002fwww\u002egoogle\u002eco\u002ejp\u002f",
			"count": 175
		}]
	}
});

ブックマーク数はそのまま count なんですが clips が配列になっているので、result.clips[0].count で取得します。
ブックマークされていないページの場合は status.code404 になります。

Topsy

おまけ。Twitter の投稿からのリンクの数を Topsy から取得して表示。
基本的には今までのと同じです。

jQuery(function ($) {

	var baseurl = location.href;

	function topsyCount(data) {
		var count = data.response.all;
		if (count > 0) {
			var user = (count === 1) ? ' tweet' : ' tweets';
			var link = '<a href="' + data.response.topsy_trackback_url + '">' + count + user + '</a>';
			$('#postTwitter').after(link);
		}
	}

	$.getJSON('http://otter.topsy.com/stats.js?url=' + encodeURIComponent(baseurl) + '&callback=?', topsyCount);

});

ちょっと違うのはリンク先。
取得データ に Topsy のページの URL が入ってるので、それを使っています。
取れるのはこんな感じ。

({
	"request":{
		"response_type":"js",
		"resource":"stats",
		"parameters":{
			"url":"http://www.google.co.jp/"
		},
		"url":"http://button.topsy.com/stats.js?url=http%3A%2F%2Fwww.google.co.jp%2F"
	},
	"response":{
			"influential":71,
			"all":4275,
			"contains":0,
			"topsy_trackback_url":"http://topsy.com/tb/www.google.co.jp/"
	}
});

使うのは respoonse 内。
all が Twitter の投稿からのリンク数で、topsy_trackback_url がリクエストしたページにリンクした投稿の一覧の URL です。
influential は、Topsy が計算して出した、その URL の影響力。RT とかで計算しているらしいです。


コードを少し修正。
必要のない行を削除。等価演算子を厳密等価演算子に修正。

Comments

monmon

あれ。@niftyクリップのXMLのパースエラーになっちゃいます?
他のと同じようにJSONP使って下のような感じにすれば取れると思いますがどうですかね?

var baseurl = location.href;

function niftyCount(obj) {
    if (obj.status.code !== ‘200’) return;

    var data = obj.result.count;
    var entryUrl = obj.result.entry_url;
    if (data > 0) {
        var user = (data === 1) ? ‘ user’ : ‘ users’;
        var link = ‘<a href="’ + entryUrl + ‘" rel="nofollow">’ + data + user + ‘</a>’

        $(‘#addNifty’).after(link);
    }

}

$.getJSON(‘http://api.clip.nifty.com/api/v1/entry?alt=json-in-script&url=’ + encodeURIComponent(baseurl) + ‘&callback=?’, niftyCount)

まとり

@monmonさん
このコードで出来ました!
api.clip.nifty.com/api/v1/counter のほうでやっていたのですが、こちらでもできました。
アドバイスありがとうございました。助かりました。

Leave a Reply