過去我從 Bloglines 跳槽到 Google Reader ,原因就不講了,在使用 Google Reader 幾年下來,我覺得 Google Reader 的優點莫過於優良的搜尋、能以 Star 保存重要的 item、讀過的 item 才會 Mark(那個 Friends’ shared items 實在很雞肋);而缺點則常是介面上的,諸如 feed 的標題不會更新、沒有手動排序、List View 不好用、不能針對單一的 feed 設定等。反過來說,Bloglines 就沒有 Star,對讀過的 item 的 mark 上做的也沒有 Google Reader 好。
除了上述那些缺點之外,Google Reader 還有一個不太好的地方,他不會提醒 feed 已經失效了,這點 bloglines 就會用 [!] 來告訴你。那我近 300 個 feed 到底有哪些是失效的?Google Reader 不會和你說,就只能自己手動檢查了。我寫了一個小程式來判斷 Google Reader 輸出的 OPML 有哪些 feed 還活著。
程式碼很簡單,主要是用 XML::OPML 和 LWP::Parallel,如果你很在意效能,我想你可能還需要對 LWP::Parallel 的參數略做調整。
#!/usr/bin/perl -w
use strict;
use XML::OPML;
use LWP::Parallel;
use encoding "utf8";
my %feeds_hash;
&main();
sub main {
my $opml = new XML::OPML;
$opml->parse ($ARGV[0]) or die $!;
foreach my $child (@{$opml->outline}) {
foreach my $x ($child) {
child_traverse($x);
}
}
my $pua = new LWP::Parallel::UserAgent;
$pua->timeout (10);
$pua->redirect (1);
foreach (keys %feeds_hash) {
$pua->register(HTTP::Request->new('GET', $_));
}
my $entries = $pua->wait();
foreach (keys %$entries) {
my $res = $entries->{$_}->response;
if ($res->code != 200) {
my $feed_text = defined $feeds_hash{$res->request->url} ?
$feeds_hash{$res->request->url} : "";
print $feed_text,
": feed url = ",$res->request->url," was ",
$res->code,": ",$res->message,"\n";
}
}
}
sub child_traverse {
my $x = shift;
if (defined(${$x}{"type"}) and ${$x}{"type"} eq "rss" ){
$feeds_hash{${$x}{"xmlUrl"}} = ${$x}{"text"};
} else {
foreach (values %{$x}) {
child_traverse($_) if (ref($_) eq "HASH");
}
}
}
Known Issues
- 遇到 Bad Behavior 會吐 403
- 在 redirect 模式下,redirect 出去會造成 $feeds_hash{$res->request->url} 會抓不到值
- response code 200 不代表是有效的 rss,如 pixnet 現在會回應「No Open」
- 不能處理 307 Temporary Redirect
- 會吐 Parsing of undecoded UTF-8 will give garbage when decoding…
也許可以用 LWP::Parallel::UserAgent 在 register 時的 callback function 中,用 XML::RSS 來判斷是不是有效的 rss,不過這樣 parsing 下來應該會很慢才是……。也許下一步我會嘗試上面這件事情,還有檢查 outline 的 text(title)和 feed 的 title 是不是相符吧,或者,該換到 beta 看起來很漂亮的 beta.bloglines.com 去。
2 responses to “檢查 OPML 的 feed 是否有效”
可以手動排序啊, 難道我們用的google reader是不一樣的? @_@
那我一定沒有好好玩過 XD