本文
twitterは流れが早すぎるのと、本家Twitterが現在から過去に向けて発言が流れるせいで、議論を追う気にならない。せっかく、#shiwake3や#f_o_sがおもしろそうなのに。
そこで、Twitter APIを使って、ハッシュタグの発言を過去に遡って取得し、それを自分の見やすい形に格納しやすいようにすることにした。このエントリーでは、Twitter APIを使ってあるハッシュタグがついた発言を遡るところまでを書く。
Ruby twitter gemのインストール
Ruby gemsを使ってインストールする。今回試した環境は以下のとおり。
- Debian GNU/Linux Squeeze
- Ruby 1.8.7 (ruby -v)
- RubyGems 1.3.5 (gem1.8 -v)
- twitter gem 0.7.5
まず、gemのアップデート
# update_rubygems か # gem1.8 update --system
次にtwitter gemのインストール
# gem1.8 install twitter
発言取得スクリプト(現在から過去)
以下のサイトを参考にスクリプトを考案。
- igaiga diary:TwitMusic でみんながどんな曲を聴いてるのか集計するコードを書いてみた
- Twitter API Wiki
- Twitter gemの簡単な使い方(英語)
- Twitter gemのリファレンス(英語)
注意すべき点は以下のとおり。
- Twitter APIは、1度のアクセスで最大100件しか発言を返してくれない
- Twitter APIは、最新から過去へ向かって発言を返してくる
- あるIPアドレスからTwitter APIへアクセスできるのは1時間あたり100回まで(これは変動するらしい)
考えたスクリプトは以下のとおり。
$KCODE = "UTF-8"
# ハッシュタグの指定
tag = 'f_o_s'
# 取得する発言のidをこの変数で制限。初期値として、最新の発言idを設定
twit_status_id_max = 5916066331
flg = true
# 後で時系列順にしたいので一度配列に格納
messageArray = Array.new
while(flg) do
# このカウンターで発言が取得できなくなったことを判定する。
counter = 0
# max(id) で発言の新しさを制限する。
Twitter::Search.new.hashed(tag).max(twit_status_id_max).per_page(100).each{|msg|
tmpArray = Array.new
localtime = Time.parse(msg.created_at).localtime
# 最新の発言idから過去に向けてどんどん遡らせる。
if msg.id <= twit_status_id_max
twit_status_id_max = msg.id
end
tmpArray.push(msg.id.to_s,msg.from_user,msg.text.strip,localtime)
messageArray.push(tmpArray)
counter = counter + 1
}
# 何も画面にでないと怖いので進捗状況の表示
puts twit_status_id_max.to_s+':'+counter.to_s
if counter == 0
flg = false
end
sleep(10)
end
# 取得した発言をCSVファイルで保存。
# Ruby標準のCSVライブラリは追記がないので
# http://d.hatena.ne.jp/unageanu/20080824/1219576777 のスクリプトを
# 利用させていただいている。
require "csv"
# 追記をサポートするように改造。
class << CSV
alias_method( :open_org, :open )
def open( path, mode, fs=nil, rs=nil, &block )
if mode == "a" || mode == "ab"
open_writer( path, mode, fs, rs, &block)
else
open_org( path, mode, fs=nil, rs=nil, &block )
end
end
end
# CSVファイルに出力
output_file = tag+'.csv'
CSV.open(output_file, 'a'){| writer |
messageArray.reverse.each{| tmpArray |
writer << tmpArray
}
}上記のスクリプトはあまりスマートではない。
発言取得スクリプト(新しい発言を追加で記録)
cronなどで回して、最新発言だけを取得したい場合は上のスクリプトで
twit_status_id_max = 最新の発言id
Twitter::Search.new.hashed(tag).max(twit_status_id_max).per_page(100).each{|msg|
〜省略〜
}となっている部分を
twit_status_id_max = 前回取得した最新発言
Twitter::Search.new.hashed(tag).since(twit_status_id_max).per_page(100).each{|msg|
〜省略〜
}とすれば良いはず。あと、微調整が必要だけど。