Web::Scraper を使ってテレビ番組表を毎日メールする

コマネチ大学数学科のような深夜番組を予約録画していると時々時間がずれていて非常に悲しいことになる。
かといって毎日番組表をチェックするのもめんどくさい。
そこで、Web::Scraper のお試しも兼ねて、番組表を見やすく加工して自分宛にメールするようにしてみた。(Web::Scraper は指定したWEBページの特定の部分を簡単に取り出すことができるライブラリ)

http://tv.goo.ne.jp/ などはとても見やすいので、このサイトの番組表を使うことにした。

大まかな処理の流れとしては、プログラムに日付とキーワードを渡してやると、その日付の番組表の部分を抜き出し、自分の指定したキーワード部分を強調表示させた形でメールする、というもの。

  • 必要なライブラリのインストール方法

以下のようにあらかじめライブラリをインストールしておく。

# cpan -i モジュール名
# cpan -i Web::Scraper
  • プログラムの使い方
# perl goo_tv.pl YYYYMMDD keyword1 keyword2 keyword3 ...

# 三日先の番組表の場合
# perl goo_tv.pl `date +%Y%m%d -d '3 day'` コマネチ のだめ 

これを /etc/cron.d/ や /etc/cron.daily/ の下に追加しておけばOK。

  • プログラムのソース
#!/usr/bin/perl

use strict;
use warnings;
use Web::Scraper;
use URI;
use Encode;
use MIME::Lite;

die 'Usage: perl goo_tv.pl YYYYMMDD keyword1 keyword2 keyword3 ...' unless  $ARGV[0] && $ARGV[1];

my $yyyymmdd = shift @ARGV;
my $area='008';  #TOKYO

my $url = "http://tv.goo.ne.jp/contents/epg/$area/VHF_1/$yyyymmdd\_0024/index.html";

# class名が「box」のdiv要素の子供のdivの子供のtable をHTML形式で抜き出し「program_table」という名前で保存する。
my $scraper = scraper {
    process 'div.box>div>table', 'program_table' => 'HTML';
};

my $res = $scraper->scrape(URI->new($url));

# 抜き出した「program_table」をHTMLに埋め込む。
my $content = qq(<html><head></head><body><table border="1">$res->{program_table}</table></body></html>);

#メールで送信するので余計なコンテンツを削除して文字数を減らす
$content =~ s!<img.*?>!!g;
$content =~ s!href=".*?"!href=""!mg;
$content =~ s!class=".*?"!!mg;

# ちゃんとutf-8にエンコードする。
$content = encode("utf-8", $content);

#キーワードを文字装飾しておく。(フォントサイズを24ドット、背景を赤に。)
foreach( @ARGV ){
    $content =~ s!$_!<span style="font-size:24px; background-color:RED">$_</span>!g;
}


#以下でHTMLメールを送信する。
my $msg = MIME::Lite->new(
                           From    =>'yoshifumi1975@example.com',
                           To      =>'yoshifumi1975@example.com',
                           Subject =>"[goo TV $yyyymmdd]",
                           Type    =>'multipart/altenative'
                           );

$msg->attach(Type     =>'text/html; charset=UTF-8',
             Data     =>$content,
             Encoding => 'base64',
             );


$msg->send('smtp','localhost', Timeout=>60, Debug=>0);