Perl | Yahoo! テレビ から番組スケジュールを取得して表示する

Perl | Yahoo! テレビ から番組スケジュールを取得して表示する

Perl だと通信もDOM操作も簡単そうだったので Perl 始めてみました。
インターネットやってて、「これ、自作プログラムで表示したいなぁ」と思うものが結構あるので…。
その第一号として、「Yahoo! テレビ から番組スケジュールを取得して表示する」、です。

#!/usr/bin/perl

use strict;
use warnings;
use v5.10;
use encoding 'utf-8';

use LWP::UserAgent;
use HTML::TreeBuilder;
use HTML::AsText::Fix;


# メイン

my $ua = LWP::UserAgent->new;
my $tree = HTML::TreeBuilder->new;

my $uri;
my $id;
my @items;

# 引数 数 チェック
if ($#ARGV == -1) {
print "引数が未定義です\n";
exit(1);
}

# 引数 文字列 チェック
if ($ARGV[0] =~ m/^http:\/\/tv.yahoo.co.jp\/program\//) {
# print "引数は URL です\n";

$uri = URI->new(get_element($ARGV[0], 'property', 'og:url')->attr('content'));
$id = {$uri->query_form}->{'sid'};
} elsif ($ARGV[0] =~ m/^[0-9]*$/) {
# print "引数は ID です\n";

$id = $ARGV[0];
} else {
print "引数が異常です\n";
exit(1);
}

# スマホ用ページから情報取得
@items = get_element('http://tv.yahoo.co.jp/s/program/schedule/';.$id, 'class', 'listRowlink tv-mb15')->look_down('_tag' => 'li');

for (@items) {
print "".HTML::AsText::Fix::as_text($_->look_down('_tag' => 'dt'), lf_char => "\n\t");
print "".HTML::AsText::Fix::as_text($_->look_down('_tag' => 'dd'), lf_char => "\n\t");
print "\b\n";
}


# 終了処理

END {
$tree->delete;
}


# 通信して、目的の要素取得

sub get_element {
my $url = $_[0];
my $attr_name = $_[1];
my $attr_value = $_[2];

my $element;
my $res;
my $content;

# 通信
$res = $ua->get($url);
if (!$res->is_success) {
print "通信失敗\n";
exit(1);
}
$content = $res->content;

# 解析
$tree->parse($content);

# DOM 操作
$element = $tree->look_down($attr_name, $attr_value);
if (!defined($element)) {
print "取得失敗\n";
exit(1);
}

return $element;
}

コマンドで表示することができれば、grep で目的の番組探せますからね。
使い方は簡単。Yahoo! テレビの番組の URL ( http://tv.yahoo.co.jp/program/~ ) を渡すだけ。
スクリプトのファイル名を ytv.pl (Yahoo! TV のつもり) だとすれば、
な感じ。
スケジュール ID を入力したほうがちょっと早いかも?

perl ytv.pl 167013

普通なら perl コマンド わざわざ打たないんだろうけど、自分の開発環境のファイルシステムが NTFS で、Linux 側から chmod で実行権限付けられなくて…。なので毎回 perl コマンド打ってます…orz

おまけ: as_text だと <br> が改行できない

HTML::AsText::Fix というのを使うと一発でできるのに、ググってみても地道に置換する方法とかばっかり出てきて、こいつが全然出てこないんだよね…なんでだろ…。

$element->as_text;

とするところを

HTML::AsText::Fix::as_text($element);

と書けばOK。 たぶんモジュールのインストールが必要。
ただ、<br> だけでなく他のタグも改行されるので、 <dl> <dt> <dd> 等で 2 重 3 重に改行されてしまうことがあるので注意!
タグごとに改行の指定ができたら楽なんだけどなー。ブロック要素/インライン要素の改行 (区切り文字) の指定しかできないもんなー。
っていうかなんか <br> 、インライン要素なのにブロック要素扱いになってるし。
インライン要素改行されまくっても困るけど、 <br> タグだけ別扱いとかにして欲しいよ…。
詳しい説明は下のページ (英語) 。

終わり

というわけで今回はこのへんで~。
またいつか~。
↓ブログランキング投票 (クリック) お願いします~