読者です 読者をやめる 読者になる 読者になる

ブログの更新頻度確認プログラム

perl 日付

RSSからブログの更新概要を取得するということをしたいのですが、
そのブログがあまりに更新されていないのであれば、対象から外したい。
単純に最新のエントリの更新時刻と現在時刻を比較するっていうのも
ありますけど、最新とその前のエントリの更新がどの程度、開いている
かというのを調べるプログラムを書いてみた。

#!/usr/bin/env perl
use strict;
use warnings;

use XML::RSS;
use LWP::UserAgent;

use DateTime;
use DateTime::Format::ISO8601;
use DateTime::Format::Mail;

my $blog_url = shift @ARGV || "http://d.hatena.ne.jp/syohex/rss";

my $ua = LWP::UserAgent->new();
$ua->agent('Mozilla/4.0 (compatible; MSIE 5.01; Windows 95)');

my $response = $ua->get($blog_url);
if ($response->is_error) {
    die "Can't download $blog_url\n";
}

my $rss = XML::RSS->new();

my $content = $response->decoded_content;

$content =~ s{encoding="[^"]+"}{encoding="UTF-8"}xms;

eval {
    $rss->parse( $content );
};
if ($@) {
    die "Can't parse $blog_url : $@\n";
}

my $now = DateTime->now();
my @dates;
my $prev;
foreach my $item (@{$rss->{'items'}}) {
    my $dt;
    if (exists $item->{'dc'}->{date}) {
        $dt = DateTime::Format::ISO8601->parse_datetime($item->{'dc'}->{date});
    } elsif (exists $item->{'pubDate'}) {
        $dt = DateTime::Format::Mail->parse_datetime($item->{'pubDate'});
    }

    if (defined $prev) {
        next if DateTime->compare($prev, $dt) == 0;
    }

    if (DateTime->compare($now, $dt) == -1) {
        next;
    } else {
        push @dates, $dt;
        last if scalar @dates >= 2;
    }

    $prev = $dt;
}

die "Error\n" if scalar @dates < 2;

my $duration = $dates[0] - $dates[1];

print $duration->years, "/";
print $duration->delta_months, "/";
print $duration->delta_days, "\n";


自分のブログの RSSで試してみると

 % perl update_frequency.pl http://d.hatena.ne.jp/syohex/rss
 0/0/2

2日前に更新している、ということがわかります。
一応未来の日付で更新されているブログは除外するようにしました。
あと調べてみるとエントリを更新すると同時に広告記事が入って最新の
2つのエントリが同じ時刻というブログサイトというのもあったので、
それも考慮しています(甘いチェックですが)。


数ヶ月単位で更新されていないものを除去するということで、
余計な巡回を行わずに済みそうですね。