最近つくったrecent_zombies - Perlで始めるTwitterタイムライン分析

>100 Views

February 01, 13

スライド概要

最近つくったrecent_zombies
Perlで始めるTwitterタイムライン分析

profile-image

NAKAYAMA Masahiro

@nekoruri

スライド一覧

秋葉原生まれ大手町育ちの歌って踊れる江戸っ子インフラエンジニア。 0と1が紡ぐ「ゆるやかなつながり」に魅せられ早20年、 SNSとCGMの力で世界を幸福にするのがライフワーク。 市民、幸福は義務です。 あなたは幸福ですか?

シェア

埋め込む »CMSなどでJSが使えない場合

各ページのテキスト
1.

最近つくった recent_zombies Perlで始めるTwitterタイムライン分析 2013-02-01 Xtone Ltd. ピザ会 Aki / @nekoruri

2.

夜中に地震が起きる

3.

とりあえずTwitterに 書き込む

4.

_人人人人人人人人人_ > 人がいっぱい! <  ̄Y^Y^Y^Y^Y^Y^Y^Y ̄

5.

可視化 市民、幸福は義務です

6.

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

7.

出力例 直近5分 直近30分

8.

出力例 直近5分 地震で跳ね上がったけど Twitterごと落ちた\(^o^)/ 直近30分

10.

つくりかた • Perl製83行 • 偉大なるCPANライブラリ – AnyEvent::Twitter::Stream – Net::GrowthForecast • 割り切った仕様 – アクセストークンは自分で取得 – 既に建ってるGrowthForecastを利用

11.

イベント駆動 • AnyEvent::Twitter::Stream – TwitterのUser Streamsを追いかける – 1件ごとにコールバックが呼ばれる – ツイートの発言日とuser.idを記録 • AnyEvent->timer – 1分毎にコールバックが呼ばれる – 直近60秒、300秒のuser.idの数を数える – GrowthForecastに投げる Net::GrowthForecast++

12.
[beta]
実際のソースコード
#!/home/masa/perl5/perlbrew/perls/perl-5.16.1/bin/perl
use strict;
use warnings;
use
use
use
use
use

AnyEvent::Twitter::Stream;
Net::GrowthForecast;
Time::Piece;
List::MoreUtils qw(uniq);
Data::Dumper;

require 'config.pl';
our ($consumer_key, $consumer_secret, $token, $token_secret);
my $gf = Net::GrowthForecast->new(host => 'localhost', port => 5125);

13.
[beta]
while(1) {
my $done = AnyEvent->condvar;
my $streamer = AnyEvent::Twitter::Stream->new(
consumer_key => $consumer_key,
consumer_secret => $consumer_secret,
token => $token,
Twitterに接続
token_secret => $token_secret,
method => 'userstream',
timeout => 45,
on_tweet => sub {
my $tweet = shift;
tweetが来たら
save_tweet($tweet);
save_tweetを呼ぶ
},
on_error => sub {
my $error = shift;
warn "ERROR: $error";
$done->send;
エラーやStreamsが切れたら
},
on_eof => sub {
次のループで再接続
$done->send;
},
);

}

my $timer;
$timer = AnyEvent->timer(
60秒ごとに
after => 0,
interval => 60,
update_gfを呼ぶ
cb => sub {
update_gf();
},
);
$done->recv;
イベント待ち開始

14.
[beta]
my %tweets;
sub save_tweet
{
my $tweet = shift;
return unless $tweet->{text};

時刻をunixtimeに

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;

1秒毎にuser_idを保存

# 古いキーを削除
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);
}

user_idをuniqして数えて
GrowthForecastに投げる

15.

幸せなUser Streams生活を!

16.

おわり