新しいfollowerやremoveした人のBioやFollowing/Followersを表示する
以前新しいfollowerやremoveした人を表示するRubyスクリプトというものを書いた。
しかし最近よくわからない外人のfollowerが増えてきていることもあり、名前だけ表示するだけではなくBioやFollowing, Followers数などがわかれば、いちいちその人のページを確認する必要もないよね、ということでBioとFollwing, Followers数も表示するRubyスクリプトを書いた。
follotter.rb
require 'rubygems' require 'mechanize' require 'kconv' class Follotter def initialize(user, pass) @agent = WWW::Mechanize.new @agent.user_agent_alias = 'Mac Safari' @agent.max_history = 1 login_form = @agent.get('http://twitter.com/').forms.action('https://twitter.com/sessions').first login_form['username_or_email'] = user login_form['password'] = pass @agent.submit(login_form) end def get_followers(command = 'check') case command when 'update' File.open("followers.txt", "w") do |io| (1..lastpage_index).each do |n| io.puts((@agent.get("http://twitter.com/followers?page=#{n}")/"a.url").map {|i| i.inner_text}) end end when 'check' followers = (1..lastpage_index).inject([]) {|memo, n| memo + (@agent.get("http://twitter.com/followers?page=#{n}")/"a.url").map {|fr| fr.inner_text} } older_followers = File.open("followers.txt", "r") {|io| io.readlines}.map {|l| l.chomp} (older_followers - followers).each do |i| info = get_followers_info(i) puts "-----------------------------------------" puts "#{i} has removed you." puts "Bio: #{info[0]}" #sjisでしか表示できない場合は info[0].tosjis のようにする puts "Following : Followers = #{info[1]} : #{info[2]}" end (followers - older_followers).each do |i| info = get_followers_info(i) puts "-----------------------------------------" puts "#{i} has started to follow you." puts "Bio: #{info[0]}" #sjisでしか表示できない場合は info[0].tosjis のようにする puts "Following : Followers = #{info[1]} : #{info[2]}" end else raise 'invalid arguments' end end private def lastpage_index num = (@agent.get('http://twitter.com/followers')/:h2).inner_text.match(/\d+/).to_s.to_i puts "Your #{num} Followers" (num%20 != 0) ? (num/20 + 1) : (num/20) end def get_followers_info(follower_name) user_page = @agent.get("http://twitter.com/#{follower_name}") bio = (user_page/"span.bio").inner_text following = (user_page/"ul.stats"/"li[1]/span").inner_text followers = (user_page/"ul.stats"/"li[2]/span").inner_text [bio, following, followers] end end if __FILE__ == $0 user = 'username' #自分のusernameに変更 pass = 'password' #自分のpasswordに変更 Follotter.new(user, pass).get_followers(*ARGV) end
基本的には前回自分が書いたものを、ujihisaが添削してくれた記事を大いに参考にしながら修正するようにした。
今まであまりArray#mapやArray#injectを使ってこなかったのだが、このように使えるんだと大変勉強になった。
あともう一つ気をつけたところは要素を指定する際にXPathをあまり使わないようにしたこと。
XPathは簡単に要素指定できるのですごく便利である一方、ページ構造に強く依存しているためページ構造の変化に弱いという欠点がある。そのあたりをタグ名やクラス名を指定するようにしてみた。
formも単純に何番目のフォームとするのではなくて、action名を元に決めることにした。(前回からログインフォームの位置が変わっていたりしたので)
Bioを表示する際に、Windowsのコマンドプロンプトを使っている人は、日本語を表示するために出力する文字の文字コードをsjisにしなくてはならない点に注意してください。
UTF-8で表示できる場合はプログラム冒頭の require 'kconv' は不要。
実行方法は前回と同じで
ruby follotter.rb update
で、比較対象となるfollowerをfollowers.txtに書き込み、
ruby follotter.rb
で、followers.txtとの差分を出力する。実行結果はたとえば下のようになる。
実行日時ごとにfollowersファイルを作成して、follower履歴みたいのをわかるようにした方がいいかなあ、と思いつつもそこまではやれてないです。