Creazy!

WEBエンジニア・ヤガーのテック・ガジェットブログ

PHP 小技集

Deliciousでサイト内ブックマーク数の合計を取得するPHPサンプル

投稿日:


はてなブックマークにはサイト内のブックマーク数合計を表示してくれるはてブカウンターというのがあります。他のSBMには無い機能ですが、サイトの人気度を示す良い指標だと思っています。
参考:はてブ数1000越え記念に、はてブカウンターの使い方を調べた
同じ事をDeliciousでもできないか?というのが今回のお題なのですが、すでに先人がRubyで実装されておりました。

del.icio.us では、 JSON URL Feeds を使用して「ページのブックマーク数」を取得できます。 「サイトの合計ブックマーク数」を取得するには、 「ページのブックマーク数」と同じ要領で、サイトが保有しているすべての URL を処理します。

via: SBM – del.icio.us ブックマーク数 | Diaspar Journal

これをPHPでやってみようと思います。

実装の準備

下準備として必要な情報をまとめておきます。
1)Deliciousのブックマーク数取得API
DeliciousではJSON Feed APIを使ってブックマーク数が取得できます。

# Summary information about a URL (as seen in the tagometer):
# http://feeds.delicious.com/v2/json/urlinfo/{url md5}

via: delicious/help/feeds

旧del.icio.usでは複数の(MD5された)URLをパラメータに渡して一度にデータを取得できました。

http://badges.del.icio.us/feeds/json/url/data?hash={url md5[&hash={url md5}...]}

新しいAPIでも同じ事ができるか試したところ問題なくできるようです。

http://feeds.delicious.com/v2/json/urlinfo/data?hash={url md5[&hash={url md5}...]}

サンプルでは一度に100件ずつ取得しています。
負荷とか大丈夫なのだろうか…。
2)サイト内のURL一覧を用意する
DeliciousではURLをキーにして検索する事ができず、同様にそのようなAPIも存在しません。
なので、調べるURLのリストを自分で用意する必要があります。
このブログはMTを使っているので、DB(MySQL)のmt_entryテーブルからSQLで公開されているエントリーURL一覧を作ってみました。
エントリーURLのフォーマットは下記のようになるので、

http://creazy.net/(年:YYYY)/(月:MM)/ファイル名.html

「公開日」と「ベースネーム(ファイル名)」を取得するSQLは下のような感じ。

select entry_created_on,entry_basename
from mt_entry
where entry_status = 2 // 公開
order by entry_created_on desc

3)JSONのパースはPEAR::Services_JSONで
DeliciousのAPIはJSONで返ってくるのでライブラリを使ってパースします。
参考:PHPでJSON – Do You PHP?
別のライブラリでもいいですけど。

サンプルコード

<?php
/**
* Deliciousのサイト内ブックマーク数合計を取得するサンプル
*
* @author yager <yager[ at ]creazy.net>
* @see http://delicious.com/help/feeds
* @memo 各URLのブックマーク数を取得するJSON API
*       http://feeds.delicious.com/v2/json/urlinfo/{url md5}
*       http://feeds.delicious.com/v2/json/urlinfo/data?hash={url md5[&hash={url md5}...]}
*
*
*/
require "JSON.php";
$api_base      = 'http://feeds.delicious.com/v2/json/urlinfo/data?hash=';
$api_delimiter = '&hash=';
//------------------------------------------------------------
// 調べるURL一覧の生成(DBから直接取得)
//------------------------------------------------------------
// DB接続
$link = mysql_connect('{DBホスト}', '{DBユーザ}', '{DBパスワード}');
mysql_select_db('{DB名}',$link);
// 公開中のエントリー一覧を取得
$sql
= "select entry_created_on,entry_basename "
. "  from mt_entry "
. " where entry_status = 2 "
. " order by entry_created_on desc ";
$res = mysql_query($sql);
$hashes = array();
$i = 0;
$j = 0;
// エントリーURLを構築
while( $row = mysql_fetch_array($res) ) {
// format : http://creazy.net/YYYY/MM/{BASE_NAME}.html
$yyyy = date('Y',strtotime($row['entry_created_on']));
$mm   = date('m',strtotime($row['entry_created_on']));
$url  = "http://creazy.net/$yyyy/$mm/".$row['entry_basename'].".html";
// 100件ずつ分けて配列に格納
if ( count($hashes[$i]) >= 100 ) $i++;
$hashes[$i][] = md5($url);
}
//------------------------------------------------------------
// ブックマーク数を取得
//------------------------------------------------------------
foreach ( $hashes as $hash ) {
// API接続
$api_url = $api_base . implode($api_delimiter,$hash);
$api_res = file_get_contents($api_url);
// JSONをパース
$json = new Services_JSON();
$list = $json->decode($api_res);
foreach ( $list as $data ) {
if ( $data->total_posts <= 0 ) continue;
echo (++$j) . ' : ' . $data->hash . ' : ' . $data->url . ' : ' . $data->total_posts . '<br />';
// ブックマーク数を加算していく
$site_total_count += $data->total_posts;
}
}
echo "total : $site_total_count<br />";
?>

上記スクリプトを実行してみた結果はこんな表示です。

1 : f3dda99e9ab4eb0c887c4097384b0958 : http://creazy.net/2008/08/apple_store_outlet_notifier.html : 1
2 : 0f30e1027140c627d5c1d742e2a0c14c : http://creazy.net/2008/08/can_isp_access_remote_desktop.html : 1
3 : b1cb03dab8c7987147f2b74ba4f0394f : http://creazy.net/2008/08/add_sbm_counter_mt_plugin.html : 1
4 : 2bcd0e1efdb594bd968e7a2739cffccc : http://creazy.net/2008/08/livedoor_reader_with_sbm_counter_greasemonkey.html : 8
5 : d34ad26f5d1700c6f3b2a960699598de : http://creazy.net/2008/08/delicious20_counter_image_api.html : 18
6 : 51c5857693640b768f51d098fedaf128 : http://creazy.net/2008/07/post_a_mixi_dialy_from_php.html : 13
7 : fa8e472e7c66897529895ae8c40bc472 : http://creazy.net/2008/07/sbm_common_api.html : 21
(省略)
95 : 69928391ce85d7754733d2e8faf87728 : http://creazy.net/2007/02/post_39.html : 1
96 : ca2f5e0033a57ea99a147f7ee6ee9598 : http://creazy.net/2006/12/javascript.html : 9
total : 595

まとめ

結構処理が重いので実用には耐えられないかもしれないです。
特にリアルタイムで出すのは厳しいのでやるとしてもバッチ処理ですかね。
ってか、これ使って何かアイデア出てくるかなぁ・・・。

-PHP, 小技集

執筆者:


comment

メールアドレスが公開されることはありません。

関連記事

検索エンジン3社が開始した、rel=canonicalの使い方

Google、Yahoo!、Live(Microsoft)の3社が「ページの正当なURL」を定義するための方法を導入する事になったようです。 headタグの中にrel=”canonical …

PinterestをAPI化するYahoo!PipesとjQueryブログパーツサンプル

最近、TwitterやFacebookのタイムラインでPinterestの名前を目にすることが多くなり、とりあえずアカウント作って試してみました。 ・Takahito Yagami (takahito …

no image

JavaScriptのポップアップウィンドウ禁止しているブラウザへの代替処理

ものすごく今更な話しかもしれないけど、最近、IE・FirefoxはもちろんSafariやOperaを同時に起動していたりして気付いたんだけど、モダンブラウザにはポップアップブロック機能(別ウィンドウを …

Re: 第3回:JavaScriptで画像サイズと合ったポップアップウィンドウを開く

[追記:2008/07/04] 更に改良したスクリプトをつくりましたので下記エントリーの方を参照して下さい。 ・Re2: 第3回:JavaScriptで画像サイズと合ったポップアップウィンドウを開く …

MacのDock風メニューを縦方向にも設置できる「MacStyleDockPlus.js」

コリスさんで以下のスクリプトが紹介されていました。 MacStyleDock.jsは、Mac OS X風のドックをPrototypeやjQueryなどのライブラリを必要とせず実装できる、わずか3KBの …

スポンサードリンク

スポンサードリンク