いろんなソーシャルブックマークサービスのブックマーク件数を数値で取得するRubyのクラス書いた

SBMはいっぱいありますけど、ブックマーク件数を取得するには、
XMLRPCやらJSONやらRESTやらでいろいろ違うんで、
簡単に取得できるクラスが欲しいと思って作りました。
Perlで書かれてるこちらをかなり参考にさせてもらってます。
というかこれのRuby版という感じになります。
ちなみに、SBMは、はてなブックマークlivedoorクリップYahoo!ブックマーク、
del.icio.usBuzzurlFC2ブックマーク、POOKMARK Airlinesの7つ利用できるようにしています。

JSONライブラリのインストール

プログラム内でJSON解析のためにgemからライブラリを持ってきてるので、
以下のようにしてインストールしてください。

# gem install json

ブックマーク件数取得プログラム

ブックマーク件数取得用ライブラリのプログラムは以下のようになります。

require 'open-uri'
require 'xmlrpc/client'
require 'rexml/document'
require 'digest/md5'

require 'rubygems'
require 'json'

class SBM
  # 初期設定
  @@sbms = {
    :hatena => {
      :name   => 'はてなブックマーク',
      :proxy  => 'http://b.hatena.ne.jp/xmlrpc',
      :entry  => 'http://b.hatena.ne.jp/entry/',
      :method => 'bookmark.getCount',
    },
    :livedoor => {
      :name   => 'livedoorクリップ',
      :proxy  => 'http://rpc.clip.livedoor.com/count',
      :entry  => 'http://clip.livedoor.com/page/',
      :method => 'clip.getCount',
    },
    :yahoo => {
      :name   => 'Yahoo!ブックマーク',
      :proxy  => 'http://num.bookmarks.yahoo.co.jp/yjnostb.php?urls=',
      :xpath  => '//SAVE_COUNT/@ct',
      :entry  => 'http://bookmarks.yahoo.co.jp/url?url=',
    },
    :delicious => {
      :name   => 'del.icio.us',
      :proxy  => 'http://badges.del.icio.us/feeds/json/url/data?url=',
      :entry  => 'http://del.icio.us/url/',
      :key    => 'total_posts',
    },
    :buzzurl => {
      :name   => 'Buzzurl',
      :proxy  => 'http://api.buzzurl.jp/api/counter/v1/json?url=',
      :entry  => 'http://buzzurl.jp/entry/',
      :key    => 'users',
    },
    :fc2 => {
      :name   => 'FC2ブックマーク',
      :proxy  => 'http://bookmark.fc2.com/image/users/',
      :regexp => /(\d+)\.png$/,
      :entry  => 'http://bookmark.fc2.com/search/detail?url=',
    },
    :pookmark => {
      :name   => 'POOKMARK Airlines',
      :proxy  => 'http://pookmark.jp/count/',
      :regexp => /(\d+)$/,
      :entry  => 'http://pookmark.jp/url/',
    }
  }

  attr_accessor :url

  def initialize(url)
    @url = url
  end

  # 一覧の出力
  def result
    self.get_all.each do |sbm, val|
      puts @@sbms[sbm][:name]
      puts "\t count:" + val[:count].to_s + "\t Entry:" + val[:entry]
    end
  end

  # すべてのSBMからブックマーク件数とSBMのURL取得
  def get_all
    sbm_counts = {}
    i = 0
    thread = []
    @@sbms.each do |sbm, etc|
      thread[i] = Thread.start do
        sbm_counts[sbm] = self.get(sbm)
      end
      i += 1
    end
    thread.each{|t| t.join}
    return sbm_counts
  end
  
  # 指定したSBMからブックマーク件数
  def get(sbm)
    case sbm
    when :hatena
      self.hatena
    when :livedoor
      self.livedoor
    when :yahoo
      self.yahoo
    when :delicious
      self.delicious
    when :buzzurl
      self.buzzurl
    when :fc2
      self.fc2
    when :pookmark
      self.pookmark
    else
      puts "Sorry, #{sbm} is not support."
    end
  end
  
  # SBMそれぞれ出力
  def hatena
    { :count => get_sbm_xmlrpc(:hatena),
      :entry => get_sbm_entry(:hatena) }
  end
  
  def livedoor
    { :count => get_sbm_xmlrpc(:livedoor),
      :entry => get_sbm_entry(:livedoor) }
  end
  
  def yahoo
    { :count => get_sbm_rest(:yahoo),
      :entry => get_sbm_entry(:yahoo) }
  end
  
  def delicious
    { :count => get_sbm_json(:delicious),
      :entry => get_sbm_entry(:delicious) }
  end
  
  def buzzurl
    { :count => get_sbm_json(:buzzurl),
      :entry => get_sbm_entry(:buzzurl )}
  end
  
  def fc2
    { :count => get_sbm_imageicon(:fc2),
      :entry => get_sbm_entry(:fc2) }
  end
  
  def pookmark
    { :count => get_sbm_imageicon(:pookmark),
      :entry => get_sbm_entry(:pookmark) }
  end

  
  private
  
  # XMLRPCによるブックマーク件数取得(hatena,livedoor)
  def get_sbm_xmlrpc(sbm)
    count = 0
    client = XMLRPC::Client.new2(@@sbms[sbm][:proxy])
    res = client.call2(@@sbms[sbm][:method], @url)
    res[1].each{|url, value| count = value } if res[0]
    return count
  end

  # REST(XML)によるブックマーク件数取得(Yahoo)
  def get_sbm_rest(sbm)
    count = 0
    open(@@sbms[sbm][:proxy] + @url) do |xml|
      doc   = REXML::Document.new(xml.read)
      count = REXML::XPath.first(doc, @@sbms[sbm][:xpath]).value.to_i
    end
    return count
  end
  
  # JSONによるブックマーク件数取得(delicious, buzzurl)
  def get_sbm_json(sbm)
    count = 0
    open(@@sbms[sbm][:proxy] + @url) do |json|
      data = JSON.parse(json.read)
      if data[0] != nil
        count = data[0][@@sbms[sbm][:key]].to_i
      end
    end
    return count
  end

  # 画像のURLからブックマーク件数取得(fc2, pookmark)
  def get_sbm_imageicon(sbm)
    count = 0
    open(@@sbms[sbm][:proxy] + @url) do |image|
      path = image.base_uri.path
      if path =~ @@sbms[sbm][:regexp]
        count = $1.to_i
      end
    end
    return count
  end

  # 入力されたURLに対応したSBMのURL表示
  def get_sbm_entry(sbm)
    url = @url
    url = Digest::MD5.hexdigest(@url) if sbm == :delicious
    return @@sbms[sbm][:entry] + url
  end
end

使い方

上で示したプログラムを「sbm.rb」というファイルで保存したとして、irbで試したものを以下に示します。
対象のURLは適当にGoogleで試してます。

irb(main):001:0> require 'sbm.rb'
irb(main):002:0> sbm = SBM.new('http://www.google.co.jp/')
irb(main):003:0> pp sbm.get_all
{:fc2=>
  {:count=>405,
   :entry=>
    "http://bookmark.fc2.com/search/detail?url=http://www.google.co.jp/"},
 :livedoor=>
  {:count=>293,
   :entry=>"http://clip.livedoor.com/page/http://www.google.co.jp/"},
 :pookmark=>
  {:count=>202, :entry=>"http://pookmark.jp/url/http://www.google.co.jp/"},
 :yahoo=>
  {:count=>62646,
   :entry=>"http://bookmarks.yahoo.co.jp/url?url=http://www.google.co.jp/"},
 :hatena=>
  {:count=>2133,
   :entry=>"http://b.hatena.ne.jp/entry/http://www.google.co.jp/"},
 :delicious=>
  {:count=>947,
   :entry=>"http://del.icio.us/url/9d0f4061beb6ae41f64eb124665e0768"},
 :buzzurl=>
  {:count=>62, :entry=>"http://buzzurl.jp/entry/http://www.google.co.jp/"}}

という感じでget_allでそれぞれのブックマーク数とSBMのURLのハッシュを取得できます。

そして、

irb(main):004:0> pp sbm.hatena
{:count=>2133, :entry=>"http://b.hatena.ne.jp/entry/http://www.google.co.jp/"}

irb(main):005:0> pp sbm.delicious
{:count=>947, :entry=>"http://del.icio.us/url/9d0f4061beb6ae41f64eb124665e0768"}

という感じで、はてブやdeliciouなどにも個別にアクセスできます。

あと、ちなみに、resultメソッドを実行すると

irb(main):006:0> pp sbm.result
FC2ブックマーク
         count:405       Entry:http://bookmark.fc2.com/search/detail?url=http://www.google.co.jp/
livedoorクリップ
         count:293       Entry:http://clip.livedoor.com/page/http://www.google.co.jp/
POOKMARK Airlines
         count:202       Entry:http://pookmark.jp/url/http://www.google.co.jp/
Yahoo!ブックマーク
         count:62646     Entry:http://bookmarks.yahoo.co.jp/url?url=http://www.google.co.jp/
はてなブックマーク
         count:2133      Entry:http://b.hatena.ne.jp/entry/http://www.google.co.jp/
del.icio.us
         count:947       Entry:http://del.icio.us/url/9d0f4061beb6ae41f64eb124665e0768
Buzzurl
         count:62        Entry:http://buzzurl.jp/entry/http://www.google.co.jp/

という感じで一覧を出力するようにしています。

以上

もし使いたい方がいれば、githubに登録してるんで自由に使ってもらってかまいません。
gist:27407 · GitHub

あと、どこかおかしいところとかあれば教えてもらうとありがたいです。