M.C.P.C.

―むり・くり―プラスコミュニケーション(更新終了)


| トップページ |

2008年3月21日 00:00

様々なオンラインブックマークサービスのブックマーク件数を画像ではなくて数値で取得

このエントリーをはてなブックマークに追加 mixiチェック

(2008-3-25 10.00追記)

高機能版の記事書きました


下のボックスにURLを入れると、いろんなオンラインブックマークでのブックマーク件数が表示されます。

ブックマークの問い合わせは最初の1回だけ行って、その後はキャッシュします。

~~~

Filename: check.cgi

#!/usr/bin/perl
use strict;
use warnings;
use Cache::File;
use CGI;
use Data::Dumper;
use HTML::Template;
use JSON::Syck;
use LWP::Simple;
use LWP::UserAgent;
use utf8;
use XMLRPC::Lite;
 
binmode STDOUT => ':utf8';
 
sbm();
 
sub sbm {
  # 初期設定
  my $cachedir = 'cache';
  my $sbms = { 
       hatena =>
       {
         proxy   => 'http://b.hatena.ne.jp/xmlrpc',
         entry   => 'http://b.hatena.ne.jp/entry/',
         method  => 'bookmark.getCount',
         message => 'このエントリーを'
                   .'はてなブックマークでブックマークしているユーザ数',
       },
       livedoor =>
       {
         proxy   => 'http://rpc.clip.livedoor.com/count',
         entry   => 'http://clip.livedoor.com/page/',
         method  => 'clip.getCount',
         message => 'このエントリーを'
                   .'livedoor Clipでクリップしているユーザ数',
       },
       pingking =>
       {
         proxy   => 'http://api.pingking.jp/xmlrpc/bookmark',
         entry   => 'http://pingking.jp/url/',
         method  => 'getCount',
         message => 'このエントリーを'
                   .'PingKingでブックマークしているユーザ数',
       },
       yahoo =>
       {
         proxy   => 'http://num.bookmarks.yahoo.co.jp/yjnostb.php?urls=',
         regexp  => 'ct="(\d+)"',
         entry   => 'http://bookmarks.yahoo.co.jp/url?url=',
         message => 'このエントリーを'
                   .'Yahooブックマークしているユーザ数',
       },
       delicious =>
       {
         proxy   => 'http://badges.del.icio.us/feeds/json/url/data?url=',
         entry   => '',
         message => 'このエントリーを'
                   .'del.icio.usでブックマークしているユーザ数',
       },
       buzzurl =>
       {
         proxy   => 'http://api.buzzurl.jp/api/counter/v1/json?url=',
         entry   => 'http://buzzurl.jp/entry/',
         message => 'このエントリーを'
                   .'Buzzurlでブックマークしているユーザ数',
       },
       fc2 =>
       {
         proxy   => 'http://bookmark.fc2.com/image/users/',
         regexp  => '/(\d+)\.png',
         entry   => 'http://bookmark.fc2.com/search/detail?url=',
         message => 'このエントリーを'
                   .'FC2ブックマークしているユーザ数',
       },
       pookmark =>
       {
         proxy   => 'http://pookmark.jp/count/',
         regexp  => '/(\d+)$',
         entry   => 'http://pookmark.jp/url/',
         message => 'このエントリーを'
                   .'POOKMARKでブックマークしているユーザ数',
       },
     };
  # 開始
  my $q      = CGI->new();
  my $url    = $q->param('url') || 'http://www.yahoo.co.jp/';
  my $counts;
  # キャッシュ
  my $cache = Cache::File->new( 
    cache_root      => $cachedir,
    default_expires => '3600 sec',
  );
  if ( $cache->exists( $url ) ) { # キャッシュ生きてる?
    $counts = eval( $cache->get( $url ) );
  }
  else {                          # キャッシュ無効?
    my $expiry = 50 + int( rand( 50 ) ).'min';
    $counts = { # SBMサービスからブックマーク件数取得
      yahoo     => get_sbm( 'yahoo',    $url ),
      hatena    => get_sbm( 'hatena',   $url ),
      delicious => get_sbm( 'delicious',$url ),
      fc2       => get_sbm( 'fc2',      $url ),
      livedoor  => get_sbm( 'livedoor', $url ),
      pookmark  => get_sbm( 'pookmark', $url ),
      buzzurl   => get_sbm( 'buzzurl'  ,$url ),
      pingking  => get_sbm( 'pingking', $url ),
    };
    local $Data::Dumper::Terse  = 1; # シリアライズ用
    local $Data::Dumper::Indent = 0; # シリアライズ用
    my $selialize = Dumper( $counts );  # シリアライズ実行
    $cache->set( $url, $selialize, $expiry ); # キャッシュ書き込み
  }
  # キャッシュ処理終わり
  
  $counts->{total} += $counts->{$_} foreach ( keys %$counts );
                                     # ブックマーク数合計
  my $html_hash = { # テンプレート差し込み用HTML項目準備
    yahoo     => sbm_html( 'yahoo'    , $url, $counts->{yahoo    } ),
    hatena    => sbm_html( 'hatena'   , $url, $counts->{hatena   } ),
    delicious => sbm_html( 'delicious', $url, $counts->{delicious} ),
    fc2       => sbm_html( 'fc2'      , $url, $counts->{fc2      } ),
    livedoor  => sbm_html( 'livedoor' , $url, $counts->{livedoor } ),
    pookmark  => sbm_html( 'pookmark' , $url, $counts->{pookmark } ),
    buzzurl   => sbm_html( 'buzzurl'  , $url, $counts->{buzzurl  } ),
    pingking  => sbm_html( 'pingking' , $url, $counts->{pingking } ),
    total     => sbm_html( 'total'    , $url, $counts->{total    } ),
    url       => $url,
  };
  my $tmpl_html = << '  END_OF_HTML';
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC 
  "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xml:lang="ja" lang="ja">
  <head>
    <meta http-equiv="Content-Type"
      content="text/html; charset=UTF-8" />
    <title>
      オンラインブックマーク件数チェック
    </title>
    <meta http-equiv="content-style-type"
      content="text/css" />
    <link rev="made" href="mailto:aab61120@pop12.odn.ne.jp" />
    <link rel="index" href="." />
    <style type="text/css">
      body {
        font-size: 13px;
        *font-size: small;
        *font: x-small;
      }
      * {
        margin: 0; 
        padding: 0;
        line-height: 1.6;
        color: #333;
      }
      body {
        background-color: #fff;
        font-family: 'メイリオ',Meiryo,
                     'MS Pゴシック',sans-serif;
      }
      input {
        font-family: Osaka, 'メイリオ',Meiryo,
                     'MS Pゴシック',sans-serif;
      }
      h1 {
        font-weight: bold;
        font-size: 122%;
        margin-bottom: 20px;
      }
      img {
        border: 0;
        vertical-align: middle;
      }
      .posted em {
        background-color: #fff0f0;
        font-weight: bold;
        font-style: normal;
      }
      .posted em a,
      .posted em a:link,
      .posted em a:visited,
      .posted em a:hover,
      .posted em a:active {
        color: #f66; 
        font-weight: bold;
        font-style: normal;
      }
      .posted strong {
        background-color: #fcc;
        font-weight: bold;
        font-style: normal;
        display: inline;
      }
      .posted strong a,
      .posted strong a:link,
      .posted strong a:visited,
      .posted strong a:hover,
      .posted strong a:active {
        color: red;
        font-weight: bold;
        font-style: normal;
        text-decoration: none;
      }
      .posted a,
      .posted a:link,
      .posted a:visited,
      .posted a:hover,
      .posted a:active {
        text-decoration: none;
        color: blue;
      }
      #content {
        margin: 20px;
      }
      div.posted {
        margin  : 20px;
        font-size: 90%;
        line-height: 19px;
      }
    </style>
  </head>
  <body>
    <div id="content">
      <h1>
        <a href="./">
          オンラインブックマーク件数チェック</a
        >
      </h1>
      <form action="check.cgi" method="get">
        <p>
          <label for="url">アドレス:</label>
          <input name="url" id="url" style="width: 80%;"
            tabindex="1" accesskey="a"
            value="<tmpl_var name="url" escape="html">" />
          <input type="submit"
            tabindex="2" accesskey="s"
          />
        </p>
        <div class="posted">
          <img src="images/yahoo.gif"
            alt="yahoo"
            width="16" height="16"
          /><tmpl_var name="yahoo">
          <br />
          <img src="images/hatena.gif"
            alt="hatena"
            width="16" height="16"
          /><tmpl_var name="hatena">
          <br />
          <img src="images/delicious.gif"
            alt="delicious"
            width="16" height="16"
          /><tmpl_var name="delicious">
          <br />
          <img src="images/fc2.gif"
            alt="fc2"
            width="16" height="16"
          /><tmpl_var name="fc2">
          <br />
          <img src="images/livedoor.gif"
            alt="livedoor"
            width="16" height="16"
          /><tmpl_var name="livedoor">
          <br />
          <img src="images/pookmark.gif"
            alt="pookmark"
            width="16" height="16"
          /><tmpl_var name="pookmark">
          <br />
          <img src="images/buzzurl.gif"
            alt="buzzurl"
            width="16" height="16"
          /><tmpl_var name="buzzurl">
          <br />
          <img src="images/pingking.gif"
            alt="pingking"
            width="16" height="16"
          /><tmpl_var name="pingking">
          <br />
          <img src="images/total.gif"
            alt="total"
            width="16" height="16"
          /><tmpl_var name="total">
        </div>
      </form>
    </div>
  </body>
</html>
  END_OF_HTML
  my $tmpl = HTML::Template->new( scalarref => \$tmpl_html );
  $tmpl->param( $html_hash );
  print $q -> header(
    -type    => 'text/html',
    -charset => 'utf-8',
  );
  print $tmpl->output();
  return;
  
  # SBMサービスからブックマーク件数取得
  sub get_sbm {
    my $service = shift;
    my $url     = shift;
    if ( $service eq 'yahoo' ) {
      return get_sbm_yahoo( $url );
    }
    elsif ( $service eq 'delicious' ) {
      return get_sbm_delicious( $url );
    }
    elsif ( $service eq 'buzzurl' ) {
      return get_sbm_buzzurl( $url );
    }
    elsif ( ( $service eq 'fc2' )
         || ( $service eq 'pookmark' ) ) {
      return get_sbm_imageicon( $service, $url );
    }
    else {
      return get_sbm_xmlrpc( $service, $url );
    }
  }
  
  # XMLRPCによるブックマーク件数取得(livedoor,hatena,pingking)
  sub get_sbm_xmlrpc {
    my $service = shift;
    my $url     = shift;
    my $result  = XMLRPC::Lite->proxy( $sbms->{$service}->{proxy} )
        ->call( $sbms->{$service}->{method}, $url )
        ->result;
    if ( $service eq 'pingking' ) {
      return $result->[0]->{ count };
    } else {
      return $result->{ $url } || 0;
    }
  }
  
  # Yahooブックマーク件数取得(REST)
  sub get_sbm_yahoo {
    my $url = shift;
    my $content = get(  $sbms->{yahoo}->{proxy}.$url );
    my $count = 0;
    if ( $content =~ m|$sbms->{yahoo}->{regexp}| ) {
      $count = $1;
    }
    return $count;
  }
  
  # del.icio.usブックマーク件数
  sub get_sbm_delicious {
    my $url = shift;
    my $data = JSON::Syck::Load( get( $sbms->{delicious}->{proxy}.$url ) );
    return $data->[0]->{total_posts} || 0;
  }
  
  # Buzzurlブックマーク件数
  sub get_sbm_buzzurl {
    my $url = shift;
    my $data = JSON::Syck::Load( get( $sbms->{buzzurl}->{proxy}.$url ) );
    return $data->[0]->{users} || 0;
  }
  
  # ブックマーク件数イメージ提供サービスから件数取得
  sub get_sbm_imageicon {
    my $servce = shift;
    my $url    = shift;
    my $ua = LWP::UserAgent->new();
    $ua->agent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
    my $req = HTTP::Request->new('GET', $sbms->{$servce}->{proxy}.$url );
    my $res = $ua->simple_request($req);
    my $location = $res->header('location');;
    my $count = 0;
    if ( $location =~ m|$sbms->{$servce}->{regexp}| ) {
      $count = 0 + $1;
    }
    return $count;
  }
  
  # ブックマーク User数 HTML生成
  sub sbm_html {
    my $service = shift;
    my $url     = shift;
    my $count   = shift;
    
    my $tag;
    my $users = 'users';
    $users = 'user'   if $count == 1;
    $tag   = 'em'     if $count > 2;
    $tag   = 'strong' if $count > 9;
    my $tag_s = $tag ? "<$tag>" : q();
    my $tag_e = $tag ? "</$tag>": q();
    
    my $tmpl_html = << '    END_OF_HTML';
          
          <tmpl_var name="tag_s">
          <a href="<tmpl_var name="entry"><tmpl_var name="url" escape="html">"
            title="<tmpl_var name="message">"
            rel="nofollow" target="_blank">
            <tmpl_var name="count"> <tmpl_var name="users"></a
          ><tmpl_var name="tag_e">
    END_OF_HTML
    
    my $tmpl = HTML::Template->new( scalarref => \$tmpl_html);
    $tmpl->param(
      url     => $url,
      entry   => $sbms->{$service}->{entry},
      message => $sbms->{$service}->{message},
      tag_s   => $tag_s,
      tag_e   => $tag_e,
      count   => $count,
      users   => $users,
    );  
    
    return $tmpl->output();
  }
 
}
 
__END__

投稿 大野 義貴 [Web] | |

トラックバック(0)

トラックバックURL: http://blog.dtpwiki.jp/MTOS/mt-tb.cgi/2414

コメントする