人気ブログランキングへ

2009年11月03日

RSSを読み込んでTwitterでつぶやく (Perl)

RSSフィードを拾い出して、Twitter にその記事情報を投稿するしくみを Perl で作ってみたのでご紹介。
※ただし、まだ動作に問題があり、改善が必要。

最近のブログには、投稿すると自動的にツイッターに記事の投稿情報を投げてくれるものもあるが、それに対応していない場合に使え そうだ。
また、RSS Reader と Twitter の両方見るのが面倒、という場合は Twitter を RSS リーダー代わりに使う、という用途もありうる。
ただ、無判断にすべて引用してしまうことになるので、ちょっと問題があるかもしれないが。

#!/usr/bin/perl
use strict;
use utf8;
use Encode::JP;
require LWP::UserAgent;
use XML::RSS::Parser;
use Net::Twitter;
my $ua = LWP::UserAgent->new;
my $rss_p = XML::RSS::Parser->new;
# 一覧ファイル読み出し
# ユーザー名<>パスワード<>タイプ<>RSSのURL<>サイトタイトル
# という書式
my $data_file = 'data.txt';
open DATA, $data_file;
flock DATA, 1;
while (my $rss = <DATA>) {
# 項目
$rss =~ s/(?:\r\n?|\n)$//;
next if $rss =~ /^#/; # コメント行は無視
my @rss_items = split /<>/, $rss;
# RSS 読み込み
my $response = $ua->get($rss_items[3]);
$response->is_success or next;
my $rss_data = $response->content;
# RSS のパース
my @articles;
if ($rss_items[2] eq 'type1') {
@articles = parser_type1($rss_p, $rss_data);
} else if ($rss_items[2] eq 'type2') {
@articles = parser_type2($rss_p, $rss_data);
}
# type3 以降も必要に応じて記述
my $tw = Net::Twitter->new(traits => [qw/API::REST/],
username => $rss_items[0],
password => $rss_items[1]);
foreach my $ar_article (@articles) {
my @article = @$ar_article;
my $message = "${article[0]} (${rss_items[4]}) ${article[1]}";
print STDERR Encode::encode('utf-8', "${message}...");
# Twitter に投稿
my $result = $tw->update($message);
print STDERR "done.\n";
sleep 30;
}
}
close DATA;
sub parser_type1
{
my ($rss_p, $rss_data) = @_;
my @articles = ();
my $rss_feed = $rss_p->parse_string($rss_data);
foreach my $item ($rss_feed->query('/channel/item')) {
my $dt_title = $item->query('title')->text_content;
my $dt_link = $item->query('link')->text_content;
push @articles, [ $dt_title, $dt_link ];
}
return @articles;
}
sub parser_type2
{
# 別のタイプのRSSパーサーを記述
}
1;
data.txt というファイルに、<> 区切りでユーザー名やパスワード、RSS のパスなどを指定してコマンドラインでこのスクリプトを実行すれば、Twitter に投稿される。

Twitter とのインターフェースには Net::Twitter というモジュール (CPAN から入手できる) を用いたが、ほかのモジュールもあるし、コマンドラインで curl を呼び出してもよい。
Things Every Developer Should Know
8) A command line is all you need to use the Twitter API
http://apiwiki.twitter.com/Things-Every-Developer-Should-Know#8AcommandlineisallyouneedtousetheTwitterAPInbsp

また、ループの最後で sleep 30 をしているが、これは Twitter のレート制限への対応である。
Rate limiting
http://apiwiki.twitter.com/Rate-limiting
1アカウントにつき、1時間に150回まで、つまり24秒に1回までという制限があるので、少し多めに、30秒間スリープしている。

前述のとおり、このコードにはいくつか問題があり、改善の必要がある。

まず、RSS の読み込み時に文字化けすることがある。
文字化けするとそれ以降すべて文字化けしてしまうようだ。
原因はまだよく検討していない。
なお、この問題は PHP で同様のコードを書くと生じないので、単に Perl でのエンコーディングの処理の問題。

また、140字の文字数制限を考慮していないので、その文字数をオーバーしている場合にはエラーを起こして途中で終了してしまう。
特に、記事のURLが長い場合もあるだろうから、対策にはちょっと工夫が必要だ (bit.ly などの URL 短縮サービスを使うなど)。

それから、どの記事を Twitter に上げたか管理していないので、処理に時間がかかってしまう。
(重複した記事は投稿されず、Twitter 側で捨ててくれるようだ)
重複投稿を避けるには、どの記事を投稿したかデータベースで管理するなど、何らかの仕組みが必要だ。
タグ:RSS twitter Perl
posted by K/I at 18:29 | 東京 ☀ | Comment(0) | TrackBack(0) | 技術メモ | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック
×

この広告は90日以上新しい記事の投稿がないブログに表示されております。