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

2008-01-07

[][] Web::Scraper for CustomFeed::Script 栗田出版販売コミック刊行予定情報  Web::Scraper for CustomFeed::Script 栗田出版販売コミック刊行予定情報 - SweetPotato::Plagger を含むブックマーク はてなブックマーク -  Web::Scraper for CustomFeed::Script 栗田出版販売コミック刊行予定情報 - SweetPotato::Plagger  Web::Scraper for CustomFeed::Script 栗田出版販売コミック刊行予定情報 - SweetPotato::Plagger のブックマークコメント

このコードの最新版はCodeReposに置いてあります。

まんがの森コミックリストよりも情報が早いと噂の栗田出版販売コミック刊行予定情報をWeb::Scraper+Plaggerでenjoy!

assets/plugins/CustomFeed-Script/bookkurita-comicdb.pl

シンタックスハイライトするとなぜか表示されないので普通のスーパーpreで。見にくくてサーセン。

#!/usr/local/bin/perl
# author: SweetPotato
use strict;
use warnings;
use utf8;

use DateTime;
use Encode qw( decode );
use URI;
use Web::Scraper 0.22;
use YAML;

my $url = 'http://www3.kuradashi-shinkan.com/kanko/comicdb.asp';

my $s = scraper {
    my $publisher;
    process '//body/div/center/table/tr[not(@align)]',
      'entry[]' => scraper {
        process '/tr/td[position()=1 or position()=2]',
          'tags[]' => ['text', \&trim];
        process '/tr/td[1]', publisher => ['text', \&trim];
        process '/tr/td[2]', series => ['text', \&trim];
        process '/tr/td[3]', title  => ['text', \&trim];
        process '/tr/td[4]', author => ['text', \&trim];
        process '/tr/td[5]', price  => ['text', \&trim];
        process '/tr/td[6]',
          date => ['text', \&trim, \&mk_date],
          part_or_day => ['text', \&trim, sub { m!/(.*?)$!; $1 } ];
        process '/tr/td[7]', isbn => ['text', \&trim];
        result qw( tags publisher series title author price date part_or_day isbn );
    };
    result qw( entry );
};
$s->user_agent->env_proxy;

my $res = $s->user_agent->get($url);
unless ($res->is_success) {
    die "GET $url failed: " . $res->status_line;
}

my @entry = @{ $s->scrape(decode('cp932', $res->content)) || [] };
for my $e (@entry) {
    $e->{body} = &mk_body($e);
    delete $e->{$_} for qw( publisher series price part_or_day isbn );
}

binmode STDOUT, ":utf8";
print YAML::Dump +{
    title => '栗田出版販売 コミック刊行予定情報',
    link  => $url,
    entry => \@entry,
};

# guess year
sub mk_date {
    my ($month, $day) = (shift =~ m!(.*)/(.*)!) or return;
    $day = &part_to_day($day);

    my $today = DateTime->now(time_zone => 'Asia/Tokyo')->truncate(to => 'day');
    my $this = $today->clone->set(month => $month, day => $day);
    my $last = $this->clone->subtract(years => 1);
    my $next = $this->clone->add(years => 1);
    my @date = sort { DateTime::Duration->compare($a->[1], $b->[1], $today) }
               map { [$_->[0], $_->[1]->is_positive ? $_->[1] : $_->[1]->inverse ] }
               map { [$_, $today - $_] } ($this, $last, $next);

    $date[0]->[0]->ymd;
}

sub mk_body {
    my $entry = shift;

    $entry->{part_or_day} =~ /^\d+$/
        ? join ', ', map { $entry->{$_} } qw( author publisher series price isbn )
        : join ', ', map { $entry->{$_} } qw( part_or_day author publisher series price isbn );
}

sub part_to_day {
    $_ = shift;
    return $_ if /^\d+$/;
    return 21 if /下/;
    return 11 if /中/;
    return 1;
}

sub trim { s/^\s*|\s*$//g; $_ }

config.yaml

plugins:
  - module: Subscription::Config
    config:
      feed:
        - url: 'script:/path/to/bookkurita-comicdb.pl'

  - module: CustomFeed::Script

  - module: Publish::iCal
    config:
      dir: /path/to/dir
      filename: kurita.ics
トラックバック - http://plagger.g.hatena.ne.jp/SweetPotato/20080107

2007-12-13

[][] Web::Scraper for CustomFeed::Script はてなハイク  Web::Scraper for CustomFeed::Script はてなハイク - SweetPotato::Plagger を含むブックマーク はてなブックマーク -  Web::Scraper for CustomFeed::Script はてなハイク - SweetPotato::Plagger  Web::Scraper for CustomFeed::Script はてなハイク - SweetPotato::Plagger のブックマークコメント

はてなハイクメイン(真ん中のエントリーが並ぶ部分)のHTML構造を変更しました。これまでの、ULタグでの構造から、DIVを使った構造に変更になっています。

ページ上部のメニュー変更について - はてなハイク日記

これに合わせて修正した。

さきほどはてなハイクでRSSフィードの出力を開始しました。

  • キーワード、asin,httpページ
  • ユーザーページ

それぞれで、RSSフィードの配信をしています。RSSファイルのURLは、ヘッダ内のlinkをご覧ください。

RSSフィードの配信開始について - はてなハイク日記

とのこと。ニーズに応じてRSSとPlaggerを使いこなすべし。

  • プロフィールアイコンをセットするようにした。
  • configを修正した。

おまけでPipes版も作った。

新サービス・はてなハイクをスクレイプ。

新着ページキーワードページユーザページFollowingProfileのどれでもうまくいくはず。

まだβだからHTMLの構造が変わってスクレイパが使えなくなるかもしれんので注意。

assets/plugins/CustomFeed-Script/hatena-haiku.pl

#!/usr/local/bin/perl
# author: SweetPotato
use strict;
use warnings;

use DateTime::Format::MySQL;
use DateTime::Format::W3CDTF;
use URI;
use Web::Scraper 0.22;
use YAML;

my $url = shift or die;

my $s = scraper {
    process '//title', title => 'text';
    process '//*[@class="entry" and not(.//div[@class="input"])]',
      'entry[]' => scraper {
        process 'img.profile-image',
          icon => ['@src', sub { +{ url => $_->as_string } } ];
        process '.title', title => 'text';
        process '.body', body => 'html';
        process '.username a', author => 'text';
        process '.timestamp a', link => ['@href', sub { $_->as_string } ];
        process '.timestamp', date => ['text', \&mk_date];
        result qw( icon title body author link date );
    };
    result qw( title entry );
};
$s->user_agent->env_proxy;

my $res = $s->scrape(URI->new($url));

binmode STDOUT, ':utf8';
print YAML::Dump +{
    title => $res->{title},
    link  => $url,
    entry => $res->{entry},
};

sub mk_date {
    my $dt = DateTime::Format::MySQL->parse_datetime(shift);
       $dt->set_time_zone('Asia/Tokyo');
    DateTime::Format::W3CDTF->format_datetime($dt);
}

config.yaml

plugins:
  - module: Subscription::Config
    config:
      feed:
         - url: 'script:/path/to/hatena-haiku.pl http://h.hatena.ne.jp/'

  - module: CustomFeed::Script

  - module: Filter::ResolveRelativeLink
トラックバック - http://plagger.g.hatena.ne.jp/SweetPotato/20071213

2007-12-09

[][] upgrader for EFT 無表情 改訂版  upgrader for EFT 無表情 改訂版 - SweetPotato::Plagger を含むブックマーク はてなブックマーク -  upgrader for EFT 無表情 改訂版 - SweetPotato::Plagger  upgrader for EFT 無表情 改訂版 - SweetPotato::Plagger のブックマークコメント

漫画(マンガ)情報サイト《無表情》以前のサイトから移転して,サイト構造も微妙に変わってるっぽかったので以前のWeb::Scraperを書き直そうと思ったんだけど,面倒になったのでEFTだけ新しくしてCustomFeed::Simpleでシンプルにハックすることにした。

assets/plugins/Filter-EntryFullText/muhyojo.pl

# author: SweetPotato

sub custom_feed_handle {
    my ($self, $args) = @_;
    $args->{feed}->url =~ qr!^http://(?:www\.)?muhyojo\.com/(?:index\.html?)?$!;
}

sub custom_feed_follow_link {
    qr!/publisher/.*?#\d+$!
}

sub handle {
    my ($self, $args) = @_;
    $args->{entry}->link =~ qr!^http://(?:www\.)?muhyojo\.com/publisher/[-\w]+/[-\w]+/(?:index\.html?)?#\d+$!;
}

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

    my ($name) = ($args->{entry}->link =~ /#(\d+)$/) or return;
    my ($data) = ($args->{content} =~ m!(<legend[^>]*><a name="?$name"?>.*?)</fieldset>!s) or return;
    $data;
}

config.muhyojo.yaml

plugins:
  - module: Subscription::Config
    config:
      feed:
        - url: http://www.muhyojo.com/

  - module: Filter::EntryFullText
  - module: Filter::ResolveRelativeLink

  - module: Filter::Rule
    rule:
      module: Expression
      expression: length($args->{entry}->title->plaintext) > 1
トラックバック - http://plagger.g.hatena.ne.jp/SweetPotato/20071209

2007-09-17

[][] scraper for CustomFeed::Config FlexComix ブラッド 修正 00:30  scraper for CustomFeed::Config FlexComix ブラッド 修正 - SweetPotato::Plagger を含むブックマーク はてなブックマーク -  scraper for CustomFeed::Config FlexComix ブラッド 修正 - SweetPotato::Plagger  scraper for CustomFeed::Config FlexComix ブラッド 修正 - SweetPotato::Plagger のブックマークコメント

ページ構造が変わっていたようなのでXPathを修正した。

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

2007-08-27

[][] widget for Widget::Simple Googleでauthorを検索  widget for Widget::Simple Googleでauthorを検索 - SweetPotato::Plagger を含むブックマーク はてなブックマーク -  widget for Widget::Simple Googleでauthorを検索 - SweetPotato::Plagger  widget for Widget::Simple Googleでauthorを検索 - SweetPotato::Plagger のブックマークコメント

エントリのauthorをGoogleで検索するウィジェットを追加する。

例えばSubscription::ToranoanaCustomFeed::MelonBooksと組み合わせれば「このサークルが気になる!」→クリックで一発検索が可能に。

assets/plugins/Widget-Simple/google_author.yaml

# author: SweetPotato
link: http://www.google.com/search
query:
  q: $args->{entry}->author
content_dynamic: Google: [% entry.author %]

config.example.yaml

plugins:
  - module: Subscription::Toranoana
    # ...

  - module: CustomFeed::MelonBooks
    # ...

  - module: Widget::Simple
    config:
      widget: google_author
トラックバック - http://plagger.g.hatena.ne.jp/SweetPotato/20070827