ログイン処理を書くのが趣味だけど、どうしてもログインを自動化しにくいサイトが有る。
たとえばYahooやニコニコ動画。ニコニコ動画はブラウザログインすると別ログインがキックアウトされる多重ログイン禁止。Yahoo JapanはログインフォームにJS検知が埋まっていて画像認証になる。回避策考えるのが面倒。msn(live.com)はすげー面倒だし。
ログインフォーム処理を高速回避
ログインフォームの作成処理を高速回避して、とりあえず目的だけ達したいことは多い。
そういう時は、ブラウザのCookieを取り出せば楽ちん。
ChromeのCookieを使うMechanizeパッチ
#coding: utf-8 require 'mechanize' class Mechanize def load_chrome_cookie(cookie_domain, cookie_path="/") case RUBY_PLATFORM when /darwin/ path_to_chrome_cookies = Object::File.expand_path("~/Library/Application Support/Google/Chrome/Default/Cookies") when /win/ path_to_chrome_cookies = Object::File.expand_path( "AppData/Local/Google/Chrome/User Data/Cookies" ,ENV["USERPROFILE"]) when /linux/ path_to_chrome_cookies = Object::File.expand_path("~/.config/google-chrome/Default/Cookies") end raise "Chromeの個人データフォルダが見つからない" unless Object::File.exists?(path_to_chrome_cookies) # www.yahoo.co.jp のようなドメインを指定した場合は .www.yahoo.co.jp に変換 cookie_domain = ".#{cookie_domain}" unless cookie_domain =~ /^\./ # puts cookie_domain db = nil begin require 'sqlite3' db = SQLite3::Database.new(path_to_chrome_cookies) db.results_as_hash = true mandatory_cookie = {} #todo secure 処理 sql = "select * from cookies where host_key like \"#{cookie_domain}\" and path = \"#{cookie_path}\" " #puts sql db.execute(sql){|r| #p r["value"] r["creation_utc"] = Time.at( Time.utc(1601,1,1,0,0,0,0).to_i , r["creation_utc"] ) r["expires_utc"] = Time.at( Time.utc(1601,1,1,0,0,0,0).to_i , r["expires_utc"] ) mandatory_cookie[r["name"]]=r["value"] } mandatory_cookie = mandatory_cookie.map{|k,v| "#{k}=#{v};" }.join(" ") #pp mandatory_cookie ensure db.close unless db.nil? end #cookie_domain = cookie_domain.gsub(/^\./, "") if cookie_domain =~ /^\./ mandatory_cookie.split(" ").each{|e| e = e.gsub(/;/, "").split("=", 2) cookie_params = {:name=>e[0],:value=> e[1], :domain => cookie_domain, :expires => Time.now + 60*60*24*30,:created_at=> Time.now - 60*60*24*30, :path => cookie_path } #p cookie_params cookie = Mechanize::Cookie.new(cookie_params) # p cookie self.cookie_jar.add(cookie) } self.cookies.map{|e| e.cookie_value + ";"}.join(" ") end end
利用サンプル
m = Mechanize.new m.user_agent_alias = 'Windows IE 7' m.load_chrome_cookie("yahoo.co.jp") m.get "http://www.yahoo.co.jp/" puts m.page.body
ログインフォームはシンプルなのがイイな。
Yahooの画像認証についてはスクリプトから回避できるけど、MSNに至っては考えるのが面倒。
どうやるのかぱっと見想像がつかない。だから諦めて目的だけ達したい。
でもどうしてもログインフォームを何とかしたいことが多いので、シンプルなのがいいな。
Javascriptを中途半端に「使う」サイトはマジ勘弁。。。
2014-11-17 追記
ChromeのCookieは、value からencrypted_value に保存されるようになってて、sqlite3を除いただけでは取れなくなったので、chrome を applescript で起動して、該当サイトに行って、script をインジェクションして、cookieを読み出さなくちゃいけない模様。もう面倒臭い・・・