最近つくったrecent_zombies - perlで始めるtwitterタイムライン分析
DESCRIPTION
最近つくったrecent_zombies Perlで始めるTwitterタイムライン分析TRANSCRIPT
最近つくった recent_zombies Perlで始めるTwitterタイムライン分析
2013-02-01 Xtone Ltd. ピザ会
Aki / @nekoruri
夜中に地震が起きる
とりあえずTwitterに 書き込む
_人人人人人人人人人_ > 人がいっぱい! <  ̄Y^Y^Y^Y^Y^Y^Y^Y ̄
市民、幸福は義務です 可視化
recent_zombies
• 自分のTLで直近N分に発言した人を数える
–要するに「今TLに居る人」の数
– Twitter API: User Streams で漏らさず取得 https://dev.twitter.com/docs/streaming-apis/streams/user
–可視化というぐらいでグラフ表示
–だいたい2時間ぐらいで作った
– とりあえず、直近5分と直近30分で運用
– githubで公開 https://github.com/nekoruri/recent_zombies
出力例
直近5分
直近30分
出力例
直近5分
直近30分
地震で跳ね上がったけど Twitterごと落ちた\(^o^)/
つくりかた
• Perl製83行
• 偉大なるCPANライブラリ
– AnyEvent::Twitter::Stream
– Net::GrowthForecast
• 割り切った仕様
–アクセストークンは自分で取得
–既に建ってるGrowthForecastを利用
イベント駆動
• AnyEvent::Twitter::Stream – TwitterのUser Streamsを追いかける
– 1件ごとにコールバックが呼ばれる
–ツイートの発言日とuser.idを記録
• AnyEvent->timer – 1分毎にコールバックが呼ばれる
–直近60秒、300秒のuser.idの数を数える
– GrowthForecastに投げる Net::GrowthForecast++
実際のソースコード
#!/home/masa/perl5/perlbrew/perls/perl-5.16.1/bin/perl use strict; use warnings; use AnyEvent::Twitter::Stream; use Net::GrowthForecast; use Time::Piece; use List::MoreUtils qw(uniq); use Data::Dumper; require 'config.pl'; our ($consumer_key, $consumer_secret, $token, $token_secret); my $gf = Net::GrowthForecast->new(host => 'localhost', port => 5125);
while(1) { my $done = AnyEvent->condvar; my $streamer = AnyEvent::Twitter::Stream->new( consumer_key => $consumer_key, consumer_secret => $consumer_secret, token => $token, token_secret => $token_secret, method => 'userstream', timeout => 45, on_tweet => sub { my $tweet = shift; save_tweet($tweet); }, on_error => sub { my $error = shift; warn "ERROR: $error"; $done->send; }, on_eof => sub { $done->send; }, ); my $timer; $timer = AnyEvent->timer( after => 0, interval => 60, cb => sub { update_gf(); }, ); $done->recv; }
Twitterに接続
エラーやStreamsが切れたら 次のループで再接続
tweetが来たら save_tweetを呼ぶ
60秒ごとに update_gfを呼ぶ
イベント待ち開始
my %tweets; sub save_tweet { my $tweet = shift; return unless $tweet->{text}; my $ts = Time::Piece->strptime($tweet->{created_at}, "%a %b %d %H:%M:%S %z %Y"); $tweets{$ts->epoch}{$tweet->{user}{id}}++; } sub update_gf { my $now = localtime->epoch; my $delete_period = 300; # 古いキーを削除 foreach my $old_key (grep { $_ < $now - $delete_period } keys(%tweets)) { delete $tweets{$old_key}; } #last60 my @last60_users = uniq( map { keys $tweets{$_} } grep { $now - 60 <= $_ } (keys %tweets)); $gf->post( 'twitter', 'recent_zombies', 'last60', scalar @last60_users); #last300 my @last300_users = uniq( map { keys $tweets{$_} } grep { $now - 300 <= $_ } (keys %tweets)); $gf->post( 'twitter', 'recent_zombies', 'last300', scalar @last300_users); }
時刻をunixtimeに
1秒毎にuser_idを保存
user_idをuniqして数えて GrowthForecastに投げる
古すぎるデータは削除
幸せなUser Streams生活を!
おわり