SweetPotato::Plagger このページをアンテナに追加 RSSフィード

2007-02-21

[] Filter::AbsolutizeEntryLink  Filter::AbsolutizeEntryLink - SweetPotato::Plagger を含むブックマーク はてなブックマーク -  Filter::AbsolutizeEntryLink - SweetPotato::Plagger  Filter::AbsolutizeEntryLink - SweetPotato::Plagger のブックマークコメント

scraperを作る時に,スクレイプ対象のページに相対リンクしか含まれていない時がよくある。そんな時はいつもextract_after_hookで,

extract_after_hook: |
  use URI;
  $data->{link} = URI->new_abs($data->{link}, $args->{feed}->url)->as_string;

ということをやって相対リンクを絶対化するんだけど,scraperを作る度にこのコードを書くのは,たった2行ではあるが面倒だし,同じコードが複数のファイルに書かれているのはどうも気持ち悪い。

Filter::AbsolutizeEntryLinkは,この作業を行うためのFilterである。フィードのリンクを基準URLとして,エントリの相対リンクを絶対化する。既にエントリのリンクが絶対的である場合には,そのリンクに対しては何もしない。

Plagger/Plugin/Filter/AbsolutizeEntryLink.pm

package Plagger::Plugin::Filter::AbsolutizeEntryLink;
use strict;
use base qw( Plagger::Plugin );

use URI;

sub register {
    my ($self, $context) = @_;
    $context->register_hook(
        $self,
        'update.entry.fixup' => \&filter,
    );
}

sub filter {
    my ($self, $context, $args) = @_;

    return if $args->{entry}->link =~ m!^https?://!;

    $args->{entry}->link(URI->new_abs($args->{entry}->link, $args->{feed}->link)->as_string);
}

1;

Filter::EntryFullTextなどを併用する際の注意

Filter::EntryFullTextなど,エントリのリンクに指定されたURLの内容を取得するFilterを併用する場合は,必ずFilter::AbsolutizeEntryLinkを最初に適用すること。つまり,

plugins:
  # ...
  - module: Filter::AbsolutizeEntryLink
  - module: Filter::EntryFullText

はOKだが,

plugins:
  # ...
  - module: Filter::EntryFullText
  - module: Filter::AbsolutizeEntryLink

はNGである。

トラックバック - http://plagger.g.hatena.ne.jp/SweetPotato/20070221