はてなスタッフ日記のOPML
はてなのことが気になって仕方がない!スタッフ日記も全部読みたい!だけど全部巡回するの面倒!というためにアンテナやRSSやらがあるのだと思いますが、OPMLでLivedoor Readerにインポートできるよう遊んでみました。
CPANサマサマだなぁ。。ほとんどコード書く必要がない。。
こんな面倒なことをしなくても、はてなスタッフ日記はどこかにRSSを吐いているところがあったような気がするのですが、どこだったかな。。
→中の人に教えてもらいました。
http://www.hatena.ne.jp/company/staff/staff-parttimer
なんか最後のrss2だけ抜いてる部分がきれいにできなくて鳥肌。Web::Scraper便利!
ループがやたら多いけど減らせるよなぁ・・・。
オブジェクト指向Perl読み中なのでそのうちやってみよう。
OPML作るところはtitleとかもっとちゃんと処理した方がイイかも。LDRだとタイトル取ってきてくれるからいらないけど。
ここがわかりやすかった。
#!/usr/bin/perl use XML::OPML; use URI; use Web::Scraper; use Encode; use List::MoreUtils qw/uniq/; use Data::Dumper; use HTML::RSSAutodiscovery; $url = "http://d.hatena.ne.jp/diarylist?mode=staff"; my $links = scraper { process '//h3/a', 'urls[]' => '@href'; result 'urls'; }->scrape(URI->new($url)); print Dumper($links); #print @$links; for my $item (@$links){ #next if $item =~ /d\.hatena/; $html = HTML::RSSAutodiscovery->new(); $rss = $html->parse($item); unless(@$rss){ warn "no RSS found"; next; } for my $l (@$rss){ if(defined $l->{type} && $l->{type} =~/rss/ig){ push @rsss,$l->{href}; } } } print Dumper @rsss; my $opml = new XML::OPML(version => "1.1"); $opml->head(); for $xml (@rsss){ if ($xml =~ m/hatena/){ if ($xml =~ m/rss2/){ $opml->add_outline( xmlUrl => $xml ); } }else{ $opml->add_outline( xmlUrl => $xml ); } } $opml->save('mySubscriptions.opml');
結果
<?xml version="1.0" encoding="UTF-8"?> <opml version="1.1"> <head> <title></title> <dateCreated></dateCreated> <dateModified></dateModified> <ownerName></ownerName> <ownerEmail></ownerEmail> <expansionState></expansionState> <vertScrollState></vertScrollState> <windowTop></windowTop> <windowLeft></windowLeft> <windowBottom></windowBottom> <windowRight></windowRight> </head> <body> <outline xmlUrl="http://d.hatena.ne.jp/stanaka/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/snishiyama/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/naoya/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/antipop/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/kawasaki/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/hatenacinnamon/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/jkondo/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/ayakoya/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/maoe/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/nmy/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/umedamochio/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/mitsuki/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/yosuke/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/reikon/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/kossy/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/mucccu/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/tikeda/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/onishi/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/secondlife/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/nagayama/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/hideoki/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/hatenakeyword/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/motemen/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/kiyohero/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/mala/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/reikon/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/shinomai/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/aql/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/AirReader/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/rapico/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/tomomii/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/rsakamot/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/hxmasaki/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/suzak/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/satzz/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/haiji505/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/yukararam/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/aircastle/rss2" /> <outline xmlUrl="http://d.hatena.ne.jp/lhapras/rss2" /> </body> </opml>