天然パーマです。

たった一つの依存で #yapcasia のトーク応募ソーシャルランキングをつくる

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を読み込みませて表にする。という具合です。以下が完成品のスクショ。

SS

はてぶ、Twitter、Facebook、トータル別にそれぞれソート出来るので便利〜

基本的に個人用につくったので、Webで公開などはしませんが、ソースは以下に置いてありますので、興味のある方はお使い下され〜