buzzurl や del.icio.us のブックマーク件数を JSON で取得して表示する Ruby スクリプト
はてなブックマーク [2007-01-28],livedoor クリップ [2007-02-10] に続いて,buzzurl と del.icio.us のブックマーク件数を取得する Ruby スクリプトを書いてみた.
API がなくて JSON しか提供されてないので,自分の生半可な知識では手のつけようがない.というわけで,JSON parser というのをありがたく頂戴してくる.
#!/usr/bin/ruby #http://webos-goodies.jp/archives/51019710.html require 'jsonparser' #require 'open-uri' require 'net/http' class BuzzurlBookmarkCounter def count urls api = "/api/counter/v1/json?url=" urls.each_with_index{|url, i| api = api + "&url=" unless i == 0 api = api + url } api = api.gsub(/\#/,'%23') src = '' Net::HTTP.version_1_2 Net::HTTP.start('api.buzzurl.jp', 80) {|http| response = http.get(api) src = response.body } # open(api) do |file| # src = file.read # end parser = JsonParser.new json = parser.parse(src) result = Hash.new json.each do |item| result.store("#{item['url']}", "#{item['users']}".to_i) end urls.each do |item| result.store(item, 0) unless ( result.key?(item) ) end return result end end if __FILE__ == $0 if ARGV.size != 1 print "usage: #{__FILE__} <urls>\n" exit else result = BuzzurlBookmarkCounter.new.count(*ARGV) result.each do |url, count| puts "#{url} #{count}" end end end
del.icio.us 用は以下.
#!/usr/bin/ruby #http://webos-goodies.jp/archives/51019710.html require 'jsonparser' #require 'open-uri' require 'net/http' require 'kconv' class DeliciousBookmarkCounter def count urls api = "/feeds/json/url/blogbadge?url=" urls.each_with_index{|url, i| api = api + "&url=" unless i == 0 api = api + url } api = api.gsub(/\#/,'%23') src = '' Net::HTTP.version_1_2 Net::HTTP.start('badges.del.icio.us', 80) {|http| response = http.get(api) src = response.body } # api = "http://badges.del.icio.us" + api # open(api) do |file| # src = file.read # end # src = src.toeuc src = src.tojis parser = JsonParser.new begin json = parser.parse(src) rescue Exception => e # return e.backtrace result = {"" => 0} return result end result = Hash.new json.each do |item| result.store("#{item['url']}", "#{item['total_posts']}".to_i) end urls.each do |item| result.store(item, 0) unless ( result.key?(item) ) end return result end end if __FILE__ == $0 if ARGV.size != 1 print "usage: #{__FILE__} <urls>\n" exit else result = DeliciousBookmarkCounter.new.count(*ARGV) result.each do |url, count| puts "#{url} #{count}" end end end
URL を引数に取ればコマンドラインから使えるし,以下のような検証用スクリプトも多分使えると思う (はてな,livedoor 用のコードも入ったままですが).
!#/usr/bin/ruby require 'hatena_bookmark_counter' require 'livedoor_clip_counter' require 'delicious_bookmark_counter' require 'buzzurl_bookmark_counter' pml = "http://nao.s164.xrea.com/td/2007-04-19.html" url = [pml,"#{pml}#p01","#{pml}#p02" ] total = 0 total2 = 0 total3 = 0 total4 = 0 result = HatenaBookmarkCounter.new.count(url) result2 = LivedoorClipCounter.new.count(url) result3 = DeliciousBookmarkCounter.new.count(url) result4 = BuzzurlBookmarkCounter.new.count(url) puts "-- hatena\n" puts result result.each do |url, count| total += count end puts total puts "-- livedoor\n" puts result2 result2.each do |url, count2| total2 += count2 end puts total2 puts "-- del.icio.us\n" puts result3 result3.each do |url, count3| total3 += count3 end puts total3 puts "-- buzzurl\n" puts result4 result4.each do |url, count4| total4 += count4 end puts total4
ちなみに Ruby の勉強は遅々として進んでないので,コードとしてはダメダメなはずです.すいません.
なんで open-uri じゃなくて NET:HTTP でやっているかというと,del.icio.us の場合になぜかうまく動かなかったから.謎.buzzurl のほうは open-uri でいけると思う.
あと,3 日間くらいハマッたのが,del.icio.us の JSON フィードにマルチバイト文字が含まれてる場合に,JSON parser が Syntax Error を投げてくる件.UTF-8 なフィードしか扱わないはずなのに,なぜかフィードを JIS にしたら解決してしまった.激しく謎.しかも再現性がどうもあやしく,EUC にして解決したこともあった.なので,とりあえず例外が来たらダミーを返すようにしてあります.
上記 2 件の謎は,単独コードでテストしたときには発生しないので,tDiary の何かと干渉してたりするのかも知れない.
あと,SBS 側のサービスが死んでた時のために,ほんとは Timeout::Error をちゃんと拾ってあげるべきなんだろうね.さぼってるけど.
さて,おかげでトップページが随分重くなってしまって,たまにコンテンツ生成に失敗するようになってしまったので,個別記事へのアクセス時にのみ,ブックマーク件数を表示させるようにした.単に tDiary の comment_new から comment_description に移しただけだが (使い方間違ってる),だいぶ軽くなったとは思います.
どんな感じになったのかは,とりあえずうちの唯一のホッテントリ [2007-04-19] でも眺めてみて下さいw