stMind

about Arsenal, Arsene Wenger, Tech, Computer vision and Machine learning

Web::ScraperとPlaggerでmixiチェックをGrowl通知する

twitterではあまり拾わない軽めの話題をマイミクと共有するツールとしてmixiチェックを使い始めました。「イイネ」とかコメントとか、ゆるい感じで付けて楽しんでおります。そこで、最新のチェックの監視を自動化してGrowl通知させ、最速リアクションが取れる環境を作ることにしました。

全体の流れ

Plaggerを使います。最新のチェックを抜き出すCustomFeed::Scriptを作り、チェックのFeed作成。Filter::RuleのDedupedで重複判定(一度通知したものは通知しない)、Notify::Growlで通知、の流れです。

最新のチェックを抜き出すCustomFeed::Script

スクリプトはassets/plugins/CustomFeed-Script/mixi_check_checker.pl at master from satojkovic's plagger - GitHubにて公開しています。

ソース全体を見ながら簡単に解説を。
WWW::Mechanizeを使ってmixiへログイン、その後follow_linkメソッドで最新のチェックのページに移動します。メールアドレスとパスワードは、Config::Pitを使って管理しています。次に、Web::Scraperで最新のチェックのHTMLから、各チェックのtitleとlinkとチェックしたuserを取り出します。最後に、チェックをentryとして含むfeedをYAMLとして出力します。なお、決め打ちっぽくなってしまいますが、Notify::Growlを使うことを想定したため、entryのtitleにuserを入れて、titleはentryのbodyに入れています。

#! /usr/bin/perl

use strict;
use warnings;

use WWW::Mechanize;
use Config::Pit;
use Web::Scraper;
use Encode;
use YAML;

my $config = pit_get('mixi.jp', require => {
    "mailaddress" => 'your mailaddress on mixi.jp',
    "password" => 'your password on mixi.jp'
});

## mixiにログイン
my $url = 'http://mixi.jp/';
my $mech = WWW::Mechanize->new();
$mech->get($url);
$mech->submit_form(
    fields => {
        email => $config->{'mailaddress'},
        password => $config->{'password'},
    },
);
$mech->get('http://mixi.jp/home.pl');

## チェックのページに移動
$mech->follow_link(url_regex => qr{recent_check\.pl});

## チェックされたリンクに関する情報を取得
my $scraper = scraper {
    process "li.listItem", "checks[]" => scraper {
        process ".title > a", title => '@alt';
        process ".name > a", user => 'TEXT';
        process ".title > a", link => '@href';
    };
};
my $res = $scraper->scrape($mech->content, $mech->uri);

## feed化
my $feed = {
    title => "mixi recent check",
    link => $mech->uri,
    entries => [],
};

for my $check (@{$res->{checks}}) {
    # entryを作成
    my $entry = {
        title => $check->{user},
        body => $check->{title},
        link => $check->{link},
    };

    push @{$feed->{entries}}, $entry;
}
binmode STDOUT, ":utf8";
print YAML::Dump $feed;

運用

YAMLは以下のように記述し、cronで1時間に1回の割合で監視するようにしました。

plugins:
  - module: Subscription::Config
    config:
      feed:
        - url: script:/path/to/mixi_check_checker.pl

  - module: CustomFeed::Script

  - module: Filter::Rule
    rule:
      module: Deduped
      path: /Users/satojkovic/cache/mixi_check.db

  - module: Notify::Growl

更新があるとこんな感じで通知されます。
f:id:satojkovic:20100925010321j:image

その他

自分のチェックを通知しても面白く無いので、自分のチェックははじくようにした方がいいかもなぁ。