github::clown::ruby-hatena

※ここで書かれているものはバージョンアップに伴って古いものとなりました.最新の説明に関しては,Hatena@Cielquis.Net で公開しています (2008/12/19).

はてブユーザ間の類似度を書いたところ,知人から

ライブラリは,作ったらgithubで公開すると受けるぜ!

と言うメッセージをもらったので,勢いで公開してみます.Hatena名前空間とか激しく被りそうですが,その辺は取り合えず様子見つつ.RAA - Ruby Application Archiveには,net-hatenaと言う同じようなことをするライブラリが既に公開されてありました・・・まぁ,ユーザ分布を調べるものとかはないのでいいか.いつの間にかイカしたライブラリになってるといいな!

公開URLは,http://github.com/clown/ruby-hatena/になります.idでclown取れたのが感激.githubに公開するにあたって少し修正を加えたので,このページを簡易リファレンスにしておきます.

Hatena::Bookmark::Entry

module Hatena
    module Bookmark
        class Entry
            attr_reader :id
            attr_reader :uri
            attr_reader :image_uri
            attr_reader :title
            attr_reader :count
            attr_reader :users
            attr_reader :related
            
            def initialize(uri = nil)
            def reset()
            def get(uri)
        end
    end
end

はてなブックマークエントリー情報取得APIのラッパクラスです.JSONの解析にrubygemsで公開されているjsonライブラリを使用しているので,rubygemsjsonがインストールされている必要があります.APIの方には,はてなブックマークエントリーページのURL(entry_url)と言うフィールドもあるようですが,現在は読み捨てています.

get()メソッドにURLを指定すると,指定したURLのはてなブックマークエントリ情報を取得し,解析します.解析に成功した場合はtrue,何らかの原因で失敗した場合にはfalseが返ります.コンストラクタにURLが指定された場合は,指定されたURLを引数にしてコンストラクタがget()メソッドを呼びます.ただし,コンストラクタにURLを指定した場合は,成功/失敗の判断ができません.

id,countは整数,uri,image_uri,titleは文字列になります.usersは{name => UserEntry}のハッシュ,relatedはRelatedEntryの配列になります.UserEntry,およびRelatedEntryの各フィールドは以下の通りです.UserEntryに関しては,date,commentは文字列,tagsは文字列の配列になります.また,RelatedEntryに関しては,id,countは整数,uri,titleは文字列になります.

module Hatena
    module Bookmark
        class UserEntry
            attr_reader :tags
            attr_reader :date
            attr_reader :comment
        end
        
        class RelatedEntry
            attr_reader :id
            attr_reader :uri
            attr_reader :title
            attr_reader :count
        end
    end
end

サンプルプログラムは以下の通りです.

#!/bin/ruby -Ku

require 'hatena'

begin
    entry = Hatena::Bookmark::Entry.new(ARGV[0])
    
    puts("id: #{entry.id}")
    puts("uri: #{entry.uri}")
    puts("image_uri: #{entry.image_uri}")
    puts("title: #{entry.title}")
    puts("count: #{entry.count}")
    puts
    
    puts("users")
    puts("--")
    entry.users.each { |key, value|
        print("#{key}, ")
    }
    puts
    puts
    
    puts("related entry")
    puts("--")
    entry.related.each { |item|
        puts(item.uri)
    }
end

Hatena::Bookmark::Count

module Hatena
    module Bookmark
        class Count
            def entry(uri)
            def site(uri)
            def asin(code)
            
            def entries(uris)
            def asins(codes)
        end
    end
end

はてなブックマーク件数取得APIをラップしたクラスです.URL,およびASINコードを指定するとブックマーク数を返します.entries(),asins()には,配列で複数のURL,ASINコードを指定することができます.これらのメソッドは,{URL/ASINコード => ブックマーク数}のハッシュで結果を返します.

Hatena::Bookmark::Trace

module Hatena
    module Bookmark
        class Trace
            attr_accessor :entries
            attr_accessor :path
            attr_accessor :count
            attr_accessor :last_index
            
            def initialize(path, start = 0)
            def reset()
            def get(n = nil)
        end
    end
end

pathを指定すると,pathで指定されたはてなブックマークページのURLの一覧を取得します.pathに指定される文字列によって,アクセス先が若干異なります.pathに指定された文字列がはてブid (/[\w\-]+/) の場合は,http://b.hatena.ne.jp/#{path}/?of=#{@last_index},それ以外の場合は,http://b.hatena.ne.jp/#{path}&of=#{@last_index}へアクセスします.get()メソッドは,指定されたidのはてブページのlast_index番目からn件ブックマークしたエントリを取得します.get()メソッドの引数が省略された場合,何件取得されるかははてなが一度に何件の情報を送信してくれるのかに依存します.

Hatena::Bookmark::Distribution

module Hatena
    module Bookmark
        class Distribution
            attr_reader :users
            attr_reader :tags
            attr_reader :sample
            
            def initialize()
            def reset()
            def add(uri)
            
            def sort_users()
            def sort_tags()
        end
    end
end

指定したURL群をブックマークしているユーザ,およびタグの分布を調べるためのクラスです.users/tagsは,それぞれユーザ名/タグ名の出現回数をハッシュで保持しています.sampleはブックマークエントリ情報を取得したURLの数を表します.add()メソッドは,指定されたURLのブックマークエントリ情報を取得し,そのエントリに現れたユーザ/タグ情報をusers/tagsに反映させます.sort_users()/sort_tags()は出現回数で降順にソートされた結果を配列で返します.

サンプルプログラムは以下の通りです.

#!/bin/ruby -Ku

require 'hatena'
require 'uri'

# parameter
b_getn = 10
b_min  = 10
b_max  = 100

begin
    tracer = Hatena::Bookmark::Trace.new(ARGV[0])
    bk = Hatena::Bookmark::Count.new
    dist = Hatena::Bookmark::Distribution.new
    
    while (dist.sample < b_getn) do
        res = tracer.get()
        if (res == 0)
            break
        end
        
        tracer.entries.each { |item|
            count = bk.entry(item)
            if (count < b_min || count > b_max)
                next
            end
            
            if (dist.add(item.uri))
                puts(item.uri)
            end
            
            if (dist.sample >= b_getn)
                break
            end
            sleep(2)
        }
        tracer.entries.clear
    end
    
    puts("--")
    puts("get #{dist.sample} entries")
    puts
    
    # ユーザ数で降順にソートした後,出力
    puts("users")
    puts("--")
    i = 0
    dist.sort_users.each { |item|
        printf("%3d %3d %s\n", i, item[1], item[0])
        i += 1
    }
    puts
    
    # タグ数で降順にソートした後,出力
    puts("tags")
    puts("--")
    i = 0
    dist.sort_tags.each { |item|
        printf("%3d %3d %s\n", i, item[1], item[0])
        i += 1
    }
    
rescue Exception => e
    $stderr.puts(e)
end