元ネタ
「情報の取得」と「情報の比較」部分はRubyにやってもらえたのですが、その間の「加工」部分は秀丸エディタと正規表現の力を借りて、手作業で
http://d.hatena.ne.jp/hrkt0115311/20090723/1248341463
せっかくなんで、もうひと押し。
(doc/"li/a.username").each do |id| user_name << id end
を
(doc/'ul[@id="bookmarked_user"]/li/a[@class="username"]').each do |id| user_name << id.inner_html end
にすれば、ユーザ名だけ取り出せるので、加工の必要がなくなるはず。
やってみる
hb_user_compare.rb
require 'rubygems' require 'hpricot' require 'open-uri' # デバッグ用 DEBUG = false # true でデバッグモード # 複数ページ取得処理:ページ読込み処理を平行して行い、待ち時間を短縮 def multi_fetch(url_list) threads,docs = {},{} url_list.uniq.each do |url| # ページ毎にスレッド作成 threads[url] = Thread.new(url) do puts "[Thread] Start: #{url}" if DEBUG begin docs[url] = Hpricot( open(url).read ) # ページを読み込んでドキュメント化 puts "[Thread] End : #{url}" if DEBUG rescue NameError => err # スレッド中で open() すると時々失敗してしまうので(NameError)リトライ処理を入れておく # 【正しい対応方法、どなたか教えて下さい】 puts "Error : #{err} (#{url})" if DEBUG Thread.pass retry end end end url_list.each do |url| puts "Waiting: #{url}" if DEBUG threads[url].join puts "Done." if DEBUG end return docs end # コマンドライン引数よりブックマークエントリページURL取得 url_list = [] ARGV.each do |url| if %r{^http://b\.hatena\.ne\.jp/entry/.+$} =~ url burl = url elsif %r{^http://} =~ url burl = 'http://b.hatena.ne.jp/entry/' + url.sub(%r{^http://}, "").gsub(/#/, "%23") elsif %r{^https://} =~ url burl = 'http://b.hatena.ne.jp/entry/s/' + url.sub(%r{^https://}, "").gsub(/#/, "%23") else burl = 'http://b.hatena.ne.jp/entry/' + url.gsub(/#/, "%23") end url_list << burl if burl puts "URL(bookmark): #{burl}" if DEBUG end # ページ取得&ユーザ抽出 docs = multi_fetch(url_list) # 複数ページ取得 def print_users(user_list,header) puts "*** #{header}" if user_list.size<2 puts "#{user_list.size} user" else puts "#{user_list.size} users" end puts user_list.sort{|a,b|a.upcase()<=>b.upcase()}.join(', ') puts '' end count,user_or_list,user_and_list = 0,[],[] url_list.each do |url| user_list = [] # ■XPathを用いて抽出 (docs[url]/'ul[@id="bookmarked_user"]/li/a[@class="username"]').each do |link| user_list << link.inner_html.gsub(/\s/,'') end print_users(user_list,url) if count == 0 user_and_list = user_or_list = user_list else user_and_list = user_and_list & user_list user_or_list = user_or_list | user_list end count+=1 end if 1 < url_list.size print_users(user_or_list,'user-list(or)') print_users(user_and_list,'user-list(and)') end
コマンドラインから
hb_user_compare.rb http://d.hatena.ne.jp/hrkt0115311/20090331/1238448821 http://d.hatena.ne.jp/hrkt0115311/20090720/1248041988
のようにやれば、
- 各URL毎のブックマークユーザリスト
- いずれかをブックマークしたユーザリスト(or)
- いずれもブックマークしたユーザリスト(and)
を表示します。
いちいち頭にhttp://b.hatena.ne.jp/entry/を付けるのは面倒なので、自動付加(なお、付けてあっても判別してそれなりに動くはず)。あと、3つ以上指定もできる、かも。