F.Ko-Jiの「一秒後は未来」

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();
}

(参考)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

著者について

fkoji

F.Ko-Ji

Webエンジニアやってます。最近は ドットインストール の開発がお仕事です。その傍ら、個人で Meity電車遅延なう梅酒.in#グラドル自画撮り部 の部室といったネットサービスを開発・運営してます。梅酒と草野球とリアル脱出ゲームが好きです。

» 詳しいプロフィールや運営サービスの一覧など