YAPC::Asia実行委員長として、ただいま皆様から頂いたトーク応募を、絶賛選考中であります。トークの選考にあたっては
また選考者だけで判断がつかない場合はFacebookのいいね!やはてなブックマーク等のフィードバックの数・内容によって採択されるかどうか決まる事がありますので、トークを応募した後はFacebook、Twitter、ブログ等での拡散をお勧めいたします。
という判断基準がありますので、当然、ソーシャルボタンの反応を可視化して見やすくしたいところ… と思っていたらMishima.pm でお世話になった dokechin さんが「YAPC::Asia 2014 Talks 総選挙」という名で、はてぶ数やツイートされた数でトークのランキングをWebで一覧出来るものをつくってました。で、この記事で紹介するのは、その「 車輪の再発明 」です。
彼のコードでは Mojo::Template を使っている割には他の Mojo::* モジュールを使っていなかったので「Mojoliciousディストリビューション」のみだけで似たようなことが出来ないかな?と考えました。MojoliciousにはMojo::UserAgentと呼ばれるHTTPクライアントのみならず、Mojo::DOMもしくはMojo::DOM::*モジュールが同封されており、HTMLのパースとその中の要素に対しCSSセレクタを使用したアクセスも可能となっています。つまりスクレイピングに便利なモジュールが cpanm Mojolicious
しただけで入っちゃうってわけです。
例えば、今年のYAPC::Asiaのトーク群をそれぞれ、いちトークずつ処理し、タイトルやURL、スピーカーの名前とアイコンURLを取得するようなコードは以下のように書けます。
my $ua = Mojo::UserAgent->new; my $tx = $ua->get('http://yapcasia.org/2014/talk/list'); my $talks = []; for my $n ( $tx->res->dom('div.talk')->each ) { my $talk = { icon_url => $n->at('div.icon a img')->attr('src'), speaker_name => $n->at('div.speaker p.name a')->text, title => $n->at('div.title a')->text, url => 'http://yapcasia.org' . $n->at('div.title a')->attr('href'), }; push @$talks, $talk; } ...;
ね?簡単でしょ?ちなみにMojo::DOMって初めて使いましたけど (・ω<)
で、今回やってみたのは、トーク情報だけをスクレイピングして、各種SNSのシェアカウントをAPIで叩く。各トークの内容をハッシュ構造にする。トークリストが配列リファレンスになるので、それをJSON形式のファイルとしてダンプ。表示はAngularJSを使ってそのJSONを読み込みませて表にする。という具合です。以下が完成品のスクショ。
はてぶ、Twitter、Facebook、トータル別にそれぞれソート出来るので便利〜
基本的に個人用につくったので、Webで公開などはしませんが、ソースは以下に置いてありますので、興味のある方はお使い下され〜