use strict; use warnings; use utf8; use Text::VimColor; use Plusen; my $p = Plusen->bootstrap({ config => { meta => { title => 'acotieのドキドキPerlプログラミング', author => 'acotie a.k.a Akiko yokoyama', email => 'acotie acotie gmail com', }, plugins => [ { module => 'ScriptLoader::Simple' }, # { module => 'Device::MozRepl', }, { module => 'Device::Term', }, { module => 'Device::Growl', }, # { module => 'Device::ControlFromFile', config => { path => '/tmp/devsumi-ctl.txt' } }, ], }, }); __DATA__ === title: はじめまして!はじめまして! === title: 今日は初めてのyokohama.pmということで === title: ものすごく緊張しています === title: 一部の界隈でマニアックなファンがいる === title: acotieです
=== title: 尊敬するPerl Hackerの === title: yappo氏が作った === title: プラガブルプレゼンツール === title: Plusenです === title: で、本題 === title: みなさんは自分の過去を振り返る習慣はありますか? === title: 適度にフィードバックすることも大切です === title: 今日は裏TwitterAPIを使ったサービスをご紹介します === title: Twitterで特定のユーザの発言の解析 === title: メインで使うモジュールは3つ list: - WWW::Mechanize - XML::RSS - MeCab === title: WWW::Mechanize list: - httpアクセスできるモジュール - LWP::UserAgenのサブクラス - リンクをたどってアクセス可能 - 規則的で面倒なことを代わりにしてくれる - 標準入力されたユーザのRSSをページ10まで取得 - API経由だと20件しか発言が取れないので強引に === title: HTTP Access and Getting Twitter-FeedURL Code code: | #!/usr/bin/perl use strict; use warnings; use WWW::Mechanize; sub _get_twitter_rss{ #リンク先設定 my $link_text = "RSS"; my $mech = new WWW::Mechanize( autocheck => 1,cookie_jar => undef ); # ユーザページにアクセス $mech->get("http://twitter.com/$ARGV[0]"); #リンクからrssをたどる $mech->follow_link(text => $link_text); return my $url = $mech->uri(); } === title: XML::RSS list: - XMLのパースを非常に楽にできるモジュール - XML::Parserを使っていて、シンプルかつ定番 - Date::Dumper,Smart::Comments等でデバッグ可能 === title: Simple XML Parse Code code: | sub main { #url取得 my $url = _get_twitter_rss(); #20post * 10page = 200post for (my $i=1; $i<=10; $i++){ my $next_url; my $result_all; if (1 < $i){ $next_url = $url . '?page=' . $i; } my $content = get($next_url); my $rss = new XML::RSS; eval{$rss->parse($content)}; for my $item (@{$rss->{'items'}}) { $result_all = encode('utf-8', $item->{title}); my ($result_id,$result_text) = split(/: /, $result_all); my $result = _parse_mecab($result_text); ### $result } } === title: MeCab (和布蕪) list: - Yet Another Part-of-Speech and Morphological Analyzer - 形態素解析をしてくれるモジュール - 奈良先端科学技術大学院大学の工藤拓氏が研究開発されている - 例:ルー語変、夙川アトムなど === title: MeCab using parse to textnode Code code: | sub _parse_mecab{ my ($txt) = @_; my $mecab = new MeCab::Tagger(""); my @result; for(my $node = $mecab->parseToNode($txt); $node; $node = $node->{next}){ next if $node->{surface} eq ""; my @feature = split ",", $node->{feature}; my $type = $feature[0]; $type = Encode::decode("utf-8", $type) unless utf8::is_utf8($type); my @TYPE_OK = qw/名詞 動詞 形容詞/; if(any { $_ eq $type } @TYPE_OK){ push(@result, $node->{surface}); }else{ ## NG #say STDERR $node->{surface}; } } return \@result; } === title: 実際に名詞、動詞、形容詞の単語が返ってきます === title: ただ解析しただけではおもしろくないので === title: 利用頻度を調べてみます === title: 余計な単語も含まれているので、フィルタリングします === title: Tokenized Keyword count Code code: | sub _process_word{ my($array_ref) = @_; my $hash = {}; for my $word (@{ $array_ref }) { my $invalid_prepost = '[_\\\)\(\)"\'@:;\.\[\]/\*<>\-\!=&,\{\}\+\| 。\$\?`、「」#\^]'; $word =~ s{^$invalid_prepost+}{}o; $word =~ s{$invalid_prepost+$}{}o; $word =~ s{^[0-9]+}{}o; $word =~ s{[0-9]+$}{}o; $hash->{$word}++; } return $hash; } === title: これで解析と集計が終わりました === title: あとはGoogle::Chartを使ってグラフ化するだけです === title: ちょっと時間が間に合わなくて === title: ここの解析までできました…。すいません>< === title: 素敵なCPANモジュールを有効活用して === title: 人間はもっと幸せになりましょう === title: おまけ === title: 個人的なWish List list: - 仕事で早くPerlができるようにすること - Plusenのシンタックスハイライト対応 - 早くCPAN Authorになること === title: no strict, no life!!(by Clouderさん) === title: 以上。ご清聴ありがとうございました。