以前にも似たようなのは書いたのだけど。
某アイドルグループに、ついに待望のファンクラブが作られた。もちろんすぐに入会しました。
そこではその子たちのマネージャーさんが不定期に日記を更新してくれるのだけど、残念なことにRSSとかも無いし、自分でログインして覗いてみないと更新されているかどうかを知ることができない。
自動化せずにはいられない。
ということで、更新チェックするプログラムを書くのだけど、、、
コンテンツが「更新されたか否か」を判定するためには、「一定間隔でコンテンツの内容をチェック」し、「前回チェックしたときと比較して差異があるか否か」を調べる必要がある。
「一定間隔で内容をチェック」すること自体は、cronなどを使えば簡単にできる(ここではWWW::Mechanizeでログイン、Web::ScraperでコンテンツHTMLの解析を行う)。
けど、「前回チェックしたときと比較して差異があるか否か」を調べるためには、前回チェックしたときの結果を何らかの形で残しておく必要がある。ファイルに書き出すだとか、DBに保存するだとかの形で。
そうするのは面倒なので、そもそもプログラムを終了させる形で書かずに「一定間隔で内容チェック」だけを行うよう実行させ続け、チェックした結果はメモリに残しておくようにする。
AnyEventのtimerで一定間隔ごとにMechanizeを走らせるようにする。
#!/usr/bin/env perl use strict; use warnings; use utf8; use AnyEvent; use Config::Pit; use Encode 'encode_utf8'; use Log::Minimal; use Try::Tiny; use Web::Scraper; use WWW::Mechanize; my $conf = +{ angeleyes => pit_get('fc.momoclo.net', require => { login_id => '会員番号', password => 'パスワード', }), }; my $previous = undef; my $cv = AE::cv; my $w = AE::timer 0, 100, sub { try { my $mech = WWW::Mechanize->new; $mech->get('https://fc.momoclo.net/pc/login.php'); $mech->submit_form( form_id => 'loginForm', fields => $conf->{angeleyes}, ); my $latest = scraper { process '#topdiary .cont li', 'contents[]' => scraper { process 'a', 'title' => 'TEXT'; process 'p.date', 'date' => 'TEXT'; }; }->scrape($mech->content)->{contents}[0]; $latest->{date} =~ s/更新//; my $current = sprintf '(%s) %s', $latest->{date}, encode_utf8 $latest->{title}; infof('latest: %s', $current); if (defined $previous && $previous ne $current) { # 何らかの通知を行う } $previous = $current; } catch { warnf('error: %s', $_); }; }; $cv->recv;
https://gist.github.com/516f6d3f7297d2865a93
プログラムはAnyEvent::timer
によって回り続けるので終了せず、定期的にコンテンツをチェックした内容は$previous
変数に保持され続け、更新されたときだけ通知処理を行う、ということがこの単一のスクリプトだけで実現できる。cronを使う必要は無い。
こういうのはNode.jsとかでsetInterval
を使っても一緒だと思うけど、Mechanize的なモジュールをよく知らないのでPerlで書いた。
WWW::Mechanize
的なのってどういうのがあるんだろう?
- アーティスト: 桃黒亭一門,もリフ,未確認少女隊UFI,林家木久扇,前山田健一
- 出版社/メーカー: キングレコード
- 発売日: 2012/09/05
- メディア: CD
- 購入: 1人 クリック: 145回
- この商品を含むブログ (67件) を見る
ももクロ春の一大事2012~横浜アリーナ まさかの2DAYS~ BD-BOX【初回限定盤】 [Blu-ray]
- 出版社/メーカー: キングレコード
- 発売日: 2012/09/05
- メディア: Blu-ray
- 購入: 10人 クリック: 113回
- この商品を含むブログ (26件) を見る
- アーティスト: ももいろクローバーZ
- 出版社/メーカー: キングレコード
- 発売日: 2012/06/27
- メディア: CD
- 購入: 4人 クリック: 433回
- この商品を含むブログ (57件) を見る
追記
少なくともPerlの場合はwhile文でループさせつつsleepで、という方法でも良かったはず。Nodeで最初にsetIntervalで書こうとしていてこういう形になってしまったのかも…