Unformed Building

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

公開:
更新:

パーマリンク

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とかで計算しているらしいです。


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