0.9.0 から nokogiri に変わってたらしく、以前書いていたものが動かなくなってた。
書き直してみたんだけどリファレンス引くのが大変・・・。メソッド呼び出しした結果でどのクラスのインスタンスが返ってくるかとか、それはどのメソッドがあるのかとか。Ruby が大クラス主義である一因かもなぁと思ったり。これが Java みたいにうじゃうじゃクラスがあったら大変だ。
リファレンスを引くのは当たり前としても、もうちょっと便利にならないかなぁと。eclipse 中毒乙か。
require 'rubygems' require 'mechanize' require 'json/lexer' class TwitterJSON # error class LoginError < StandardError ; end class OverLimitError < StandardError ; end # RETRY_MAX = 5 # constructor def initialize(user_name , password , option = {}) option[:max_history] ||= 1 @user_name = user_name @password = password @logined = false @agent = WWW::Mechanize.new @agent.max_history = option[:max_history].to_i end # get json def json login unless @logined parse end # # private methods # private def login start = Time.now puts "login ... start" if $DEBUG page = @agent.get('http://twitter.com') form = page.forms[0] form["session[username_or_email]"] = @user_name form["session[password]"] = @password page = @agent.submit(form) if page.root.xpath('.//body').attr("id") == "home" puts "login ... end (" + (Time.now - start).to_s + ")" if $DEBUG @logined = true else raise LoginError.new end end def parse start = Time.now puts "parse ... start" if $DEBUG ol = nil 0.upto(RETRY_MAX){|i| puts "request try #{i}" if $DEBUG page = @agent.get('http://twitter.com/') ol = page.root.xpath(".//ol")[0] break if ol } raise OverLimitError.new unless ol list = [] ol.xpath(".//li").each{|li| next unless li.elem? screen_name = li.xpath(".//a[@class='screen-name']")[0].inner_text name = li.xpath(".//img")[0].attribute("alt").value img = li.xpath(".//img")[0].attribute("src").value text = li.xpath(".//span[@class='entry-content']")[0].inner_html.strip text = text.gsub(/@<a .*?>(.*?)<\/a>/ , "@\\1") text = text.gsub(/<a href="(.*?)".*?>.*?<\/a>/ , "\\1") date = li.xpath(".//span[@class='published']")[0].inner_text id = li.attribute("id").value.split("_")[1] user = {"name" => name , "screen_name" => screen_name , "profile_image_url" => img} list << {"user" => user , "text" => text , "created_at" => date , "id" => id} } puts "parse ... end (" + (Time.now - start).to_s + ")" if $DEBUG list.to_json end end
使う時は
twitter = TwitterJSON.new("id","password") puts twitter.json