PerlでRSSを取得するメモ
メモ代わりのエントリー。PerlでRSSフィードを取得してデータベースに登録してみる。
(実際のスクリプトはこちら→rssfeed.cgi)
●使用したモジュール
- LWP::Simple サイトを取得
- XML::RSS RSSを解析
- DBI データベース操作
- CGI CGIの操作
データベースの接続は$dbh = DBI->connect($data_source,$username,$password);。$data_sourceはMySQLの場合は「DBI:mysql:データベース名:host=ホスト名」となる。切断は$dbh->disconnect();。SQLの実行は、$sth = $dbh->prepare(“SQL文”);で準備をして$sth->execute;で実行できる。selectall_arrayrefのように、prepareをせずに一気にexecuteして結果を取得するメソッドもある。executeメソッドに与える引数は、SQL文に与えられた「?」に代入される。これは、SQLインジェクションの対策にもなる。
LWP::Simpleのget関数でRSSフィードを取得。$rss = new XML::RSS;としてから、$rss->parse(get($feed_url));とすれば、RSSフィードがパースされる。$rss->channel->{‘title’}にRSSフィードのタイトル、$rss->channel->{‘link’}にRSSフィードの生成元のページのURLといったように、解析結果はハッシュのリファレンスとして$rssに格納される。実際は、XML::RSSのparseは失敗すると例外を返すので、evalで回避させるといい。
●サンプルスクリプト
#!/usr/bin/perl
use strict;
use LWP::Simple;
use XML::RSS;
use DBI;
use CGI;
print "Content-type: text/html; charset=utf-8\n\n";
# database open
my $dbh = &db_open();
sub db_open() {
 my $d = 'DBI:mysql:データベース名;host=ホスト名';
 my $u = 'ユーザ名';
 my $p = 'パスワード';
 my $dbh = DBI->connect($d, $u, $p);
 return $dbh;
}
# set utf-8
&db_set_char($dbh, 'UTF8');
sub db_set_char {
 my $dbh = shift;
 my $char = shift;
 my $sth = $dbh->prepare("SET CHARACTER SET $char");
 $sth->execute;
 $sth->finish;
}
print <<__HTML;
<html>
<head>
</head>
<body>
<form name="form1" method="post" action="rssfeed.cgi">
RSSフィード
<input type="text" name="feed_url" size="36" maxlength="255">
<input type="hidden" name="mode" value="regist">
<input type="submit" value="登録">
</form>
</body></html>
__HTML
my $q = new CGI;
if ($q->param('mode') eq 'regist') {
 my $sql = "select id from feed where feed_url = ?";
 my $sth = $dbh->prepare($sql);
 $sth->execute($q->param('feed_url'));
 my $num = $sth->fetchrow_array;
 $sth->finish;
 if ($num > 0) {
  print 'そのフィードは既に登録済みです。';
 } else {
  ®ist_feed($q->param('feed_url'));
  print 'フィードの登録が完了しました。';
 }
}
my $sql = "select * from feed";
my $ary_ref = $dbh->selectall_arrayref($sql);
foreach my $row (@{$ary_ref}) {
 print '<li><a href="'.$row->[3].'">'.$row->[2].'</a></li>';
}
sub regist_feed {
 # URL of RSS feed
 my $feed_url = shift;
 # get the rss feed
 my $input = get($feed_url);
 my $rss = new XML::RSS;
 $rss->parse($input);
 # feed title
 my $feedtitle = $rss->channel->{'title'};
 my $feed_link = $rss->channel->{'link'};
 # datetime
 my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
 $year += 1900;
 $mon++;
 $sec = ($sec < 10) ? '0'.$sec : $sec;
 $min = ($min < 10) ? '0'.$min : $min;
 $hour = ($hour < 10) ? '0'.$hour : $hour;
 $mday = ($mday < 10) ? '0'.$mday : $mday;
 $mon = ($mon < 10) ? '0'.$mon : $mon;
 my $datetime = "$year-$mon-$mday $hour:$min:$sec";
 # feed insert
 my $sql = "insert into feed (feed_url, feed_title, feed_link, create_time, update_time) values (?, ?, ?, ?, ?)";
 my $sth = $dbh->prepare($sql);
 $sth->execute($feed_url, $feedtitle, $feed_link, $datetime, $datetime);
 $sth->finish;
}
print <<__HTML;
</body>
</html>
__HTML
&db_close($dbh);
sub db_close() {
 my $dbh = shift;
 $dbh->disconnect();
}
(参考)
 

 
コメントを残す