TwitterをHTMLから取得してPlaggerで使おう
前回,Plagger を使って Twitter のフィードから Tumblr へ流しましたが,僕がせっかく 書き上げるとすぐに Twitter は遅延してしまいました.あほですね.たまにちゃんと 動いているのですが,どうもフィードの更新が遅いです.Fav をした直後に見ると, ブラウザから WEB ページで見るとちゃんと新しい Fav も追加されているのに, フィードを見ると追加されていないことがありました.
いずれにせよ,Twitter の API は不安定きわまりないので,せっかくですから HTML を解析してこちらでフィードを作ってしまうことにしましょう. Plagger にもフィードを吐かないところ用に Plagger::Plugin::CustomFeed という分類が あります.こいつに従っていきましょう.メインのモジュールは Web::Scraper です.
Plagger::Plugin::CustomFeed::Twitter
目的としては,TwitterAPI で取得できるフィードを HTML から自作してしまうことです. が,完全にまねるのはめんどくさかったので,最小限にしました.まぁ必要とあらば ソースをいじればできるので.
Web::Scraper はとっても便利です.UserAgent とか作らなくてもさくっと GET してくれるし,class とか id とか結構ふってあるサイトだったら, それを指定するだけですぐに要素が取って来れます.しかも配列に格納してくれるので あとの処理も簡単・・・,のはずが$res->{entry}をどうやってforeachに渡したらいいのか 分からず数時間悩みましたw結論としてはforeach (@{$res->{entry}})としてあげると うまく渡せました.さすが Perl,わけがわかりません w
というわけで,ソース.いつもどおり github に置いてあります.
lib/Plagger/Plugin/CustomFeed/Twitter.pm
package Plagger::Plugin::CustomFeed::Twitter;
use strict;
use base qw( Plagger::Plugin );
use URI;
use Web::Scraper;
sub register {
my($self, $context) = @_;
$context->register_hook(
$self,
'subscription.load' => $self->can('load'),
);
}
sub load {
my($self, $context) = @_;
my $feed = Plagger::Feed->new;
$feed->aggregator(sub { $self->aggregate(@_) });
$context->subscription->add($feed);
}
sub aggregate {
my ($self, $context, $args) = @_;
my $uri = new URI($self->conf->{uri}[0]);
$context->log(info => $self->conf->{uri}[0]);
my $entry = scraper {
process 'span.entry-content', post => 'TEXT';
process 'a.entry-date', url => '@href';
process 'span.published', date => '@title';
process 'div>strong>a', id => 'TEXT';
};
my $res = scraper {
process 'td.status-body', 'entry[]' => $entry;
}->scrape($uri);
# print $res->{entry}[0]->{post};
my $feed = Plagger::Feed->new;
$feed->type('twitter');
foreach my $line (@{$res->{entry}}){
$context->log(debug => $line->{post});
my $entry = Plagger::Entry->new;
my $post = $line->{id}. ": ". $line->{post};
my $dt = eval { Plagger::Date->parse_dwim($line->{date}) };
$entry->date($dt) if $dt;
$entry->body($post);
$entry->author($line->{id});
$entry->title($post);
$entry->link($line->{url});
$feed->add_entry($entry);
}
$context->update->add($feed);
}
1;
使い方
前回の YAML ファイルの Subscription::Config の部分をそっくりそのまま CustomFeed::Twitter に変えれば使えるはずです.
plugins:
- module: CustomFeed::Twitter
config:
uri:
- http://twitter.com/riywo/favorites
試してませんが,多分 Fav じゃなくても普通のページでも使えるんじゃないかな. というわけで,これで API が動かなくても WEB が生きてれば使える!
参考にしたのは下のページ.こちらの CustomFeed::Twitter は Net::Twitter を 使ってるので結局 API 経由ですね.
ちなみに,仕上げる直前くらいで,CustomFeed::Script の存在を知りました. これなら Scraping の部分だけ assets で書けばいいっぽい.まぁいいや,あとで 時間があればこっちにあわせるかもしれない.