(ruby)(Twitter)(フォロワーを取得する)(OAuth認証版)(Gems は OAuth のみを利用版)

 さて 以前は Basic認証版の フォロワー取得の方法を考えてみましたが
今回は ついに OAuth認証版を考えてみました

 OAuthの場合は アプリケーションの登録が必要になりますので
あらかじめ http://twitter.com/apps に 適当なアプリケーション名を
クライアントアプリケーション として登録しておきます
ついでに ConsumerKey と ConsumerSecret の値を控えておきます
この二つの値が アプリケーションを特定するために必要なものとなります
↓のスクリプトに必要となります

 続いて そのアプリケーションが 各ユーザのアカウントでアクセスするために必要なのが
「アクセストークン」です、アクセストークンを取得するためには
ConsumerKey と ComsumerSecret の値を元に生成された Twitter上のアドレスにアクセスし
各ユーザが Twitterにログインし アクセスを許可する事によって得られます
そうやって得た アクセストークンを元に TwitterAPIにアクセスする事が可能になるわけです

 ただし アプリケーションが終わると アクセストークンのインスタンスは破棄されるので
二度目以降も同じ様な手順が必要になってしまいます、 ちょっと面倒ですよね
そこで アクセストークンの Token と Secret の値を控えておけば
二度目以降は その値を元に 即座にアクセストークンを生成する事が可能になります

 ということで考えたのは
ConsumerKey と ComsumerSecret と AccessToken と AccessSecret の値を とりあえず保存しておき
必要な時に それらの値を元に アクセストークンを生成するということです
そうすれば 二度目以降や、 その他のスクリプトを実行する時でも この値を参照すればよくなります

 ということで まずは 4つの値を ひとつのファイルに書き出す スクリプトです
端末 で このスクリプトを実行すると ブラウザが起動し 認証用のページが開きますので
利用したいアカウントでログインした後に 認証をして
その後に表示された数値を 端末に コピペします
エラーなく終われば スクリプトと同じフォルダに
OAuthKeys.txt というファイルが生成されます
#!/usr/bin/ruby -Ku


# Ubuntu 10.04
# ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]
# RubyGems 1.3.5
# oauth 0.4.1
# Encode UTF-8
# FileType Unix

require 'rubygems'
require 'oauth'

CONSUMER_KEY = '登録したアプリケーションの ConsumerKey'
CONSUMER_SECRET = '登録したアプリケーションの ConsumerSecret'

consumer = OAuth::Consumer.new(
	CONSUMER_KEY, CONSUMER_SECRET, {:site => '[]http://twitter.com[]'}
)
request_token = consumer.get_request_token
puts('ブラウザを起動して 認証ページを開きます')
fork(){
	system('firefox ' << request_token.authorize_url)
	exit(0)
}
sleep(3)
print('認証後に表示された数値を入力してください >')
access_token = request_token.get_access_token({:oauth_verifier => gets().chomp()})

f = open('OAuthKeys.txt', 'w')
f.print(
	CONSUMER_KEY << "\n" <<
	CONSUMER_SECRET << "\n" <<
	access_token.token << "\n" <<
	access_token.secret
)
f.close
 Windows版などの場合 fork→systemの流れで firefoxを起動しているところが動作しないと思うので
各自うまく動くように書き直してください 笑)
Windows上で動かす場合の書き換えサンプル

#!ruby -Ku # WindowsXP Pro SP3 # ruby 1.9.1p429 (2010-07-02 revision 28523) [i386-mswin32] # RubyGems 1.3.7 # oauth 0.4.1 # Encode UTF-8 # FileType dos require 'rubygems' require 'oauth' require 'nkf' require 'Win32API' def shell_execute(exec_filename, exec_option) return Win32API.new('shell32', 'ShellExecute', %w(p p p p p i), 'l').call( 0, 'open', exec_filename, exec_option, '', 1 ) end CONSUMER_KEY = '登録したアプリケーションの ConsumerKey' CONSUMER_SECRET = '登録したアプリケーションの ConsumerSecret' consumer = OAuth::Consumer.new( CONSUMER_KEY, CONSUMER_SECRET, {:site => '[]http://twitter.com[]'} ) request_token = consumer.get_request_token puts(NKF.nkf('-Ws','ブラウザを起動して 認証ページを開きます')) shell_execute('C:\Program Files\Mozilla Firefox\firefox.exe', request_token.authorize_url) sleep(3) print(NKF.nkf('-Ws','認証後に表示された数値を入力してください >')) access_token = request_token.get_access_token({:oauth_verifier => gets().chomp()}) f = open('OAuthKeys.txt', 'w') f.print( CONSUMER_KEY << "\n" << CONSUMER_SECRET << "\n" << access_token.token << "\n" << access_token.secret ) f.close
 ただ注意点としては
これらの値が 他人にばれてしまうと 成りすましの被害などにあってしまうことが考えられるので
取り扱いには十分注意してください、心配な場合はそのつど OAuthKeys.txt を削除した方がいいかもしれません


 続いて 実際に フォロワーを取得する部分です
フォロワー一覧を取得する部分の考え方は 基本的には Basic認証版と ほとんど変わりません
Basic認証版と違う部分は アクセストークンを生成するところですが
流れを 順追ってみてみれば そんなに複雑な事ではないかと思います
#!/usr/bin/ruby -Ku

# Ubuntu 10.04
# ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]
# RubyGems 1.3.5
# oauth 0.4.1
# Encode UTF-8
# FileType Unix

require 'rubygems'
require 'oauth'
require 'rexml/document'

MAX_LOOP = 5

keys = open('OAuthKeys.txt', 'r').readlines()

access_token = OAuth::AccessToken.new(
	OAuth::Consumer.new(
		keys[0].chomp(),
		keys[1].chomp(),
		{:site => '[]http://twitter.com[]'}
	),
	keys[2].chomp(),
	keys[3].chomp()
)

c = '-1'
buf = ''

MAX_LOOP.times{
	xml = REXML::Document.new(
		access_token.get('/statuses/followers.xml?cursor=' << c).body
	)
	c = xml.elements['users_list/next_cursor'].text
	xml.elements.each('users_list/users/user'){|usr|
			buf <<
			usr.elements['id'].text << "\t" <<
			usr.elements['screen_name'].text << "\t" <<
			usr.elements['name'].text << "\n"
	}
	if c == '0'
		break
	end
	sleep(3)
}

puts(buf)

 今回は 二種類のスクリプトを書きましたが
その中に出てくる access_token は どちらも同じものです
access_token = request_token.get_access_token({:oauth_verifier => gets().chomp()})



access_token = OAuth::AccessToken.new(
	OAuth::Consumer.new(
		keys[0].chomp(),
		keys[1].chomp(),
		{:site => '[]http://twitter.com[]'}
	),
	keys[2].chomp(),
	keys[3].chomp()
)

access_token は 同じ内容のインスタンスです
access_token.token や access_token.secret の値が 残らないように
毎回 認証ページを開く必要のあるスクリプトを書く場合は
認証後に出来ている access_token をそのまま利用すれば
TwitterAPIにアクセス出来ます

Basic認証版は → http://d.hatena.ne.jp/morakana/20100501/1272750864