まとめて読もう! 2012年 アドベントカレンダー はてブ数ランキングベスト30 を作ってみた。
あけましておめでとうございます。今年も from scratchと yosuke_furukawaをよろしくお願いいたします。
Perlでプログラム初めをしてました。2012年のアドベントカレンダー記事一覧をスクレイピングしてURLだけ取得し、はてなブックマーク数でランキングを作ってみました。
ランキング
こうしてみると、HTML5,PHP, jQuery等の技術トピックに加えてVimやSublime Text2等のエディタが人気だと感じました。
1位の記事もVimだし。去年流行りだしたSublime Text2の人気もすごいですね。Vim vs Emacs vs Sublimeが丁度三国志の様相を呈してきて面白くなりそうです。あと、gitもユーザーごとにTipsがあってアドカレ向きのトピックだと感じました。
あとはkayac、クラスメソッド等の企業でのアドベントカレンダーも人気でした。
こういうところからも企業風土が見えていいですね(kayacの1位の記事がおっぱいの記事というのがなんとも)。
個人的には、ビット演算アルゴリズムまとめが面白かった。
へ、変態っ!!読めないからやめてっ!bit使ったデータ構造・アルゴリズム実装集 - Negative/Positive Thinking
ランキング入りしてないけど面白かった奴
あと、作っている最中に見つけた面白そうなアドベントカレンダーも一緒に紹介しておきます。
子育てエンジニア advent calendar 2012 : ATND
子育てエンジニアがお役立ち育児グッズをひたすら紹介する Advent Calendar 2012
子供を持つエンジニアがどうやって自己研鑚に励んでいるか、という話が良かったです。
この中でもすたじおなんとかさんと皆さんから呼ばれている@studio3104さんの以下の記事が良かったです。
孕ませ駆動結婚のおかげさまでそこそこまともにサラリーマン生活を営めている話 #childrenac2012 - studio3104::Blog
あとは皆のペット自慢アドカレとか。
Tech Pets Advent Calendar 2012
変態アドカレとか。
HENTAI Advent Calendar 2012 - 変態アドベントカレンダー - : ATND
多少斜め上を目指している方々のエントリも面白かった。
スクレイピング方法
というわけで、ランキングの話は終わりです。
あとはこのランキングをどうやって作ったかというPerlの話です。
コード
なんというか、もう少しやりようはなかったのか、という感じですが公開します。
■アドベントカレンダー一覧からアドベントカレンダーの募集ページだけを引っ張ってくる(スクレイピングする)コード
use URI; use Web::Scraper; use strict; use warnings; my $NAVER_URL = 'http://matome.naver.jp/odai/2135217818800380701?page='; for (1..8) { my $naver = scraper { process 'a.mdMTMWidget01ItemUrl01Link', 'links[]' => '@href'; }; my $url = $NAVER_URL.$_; my $res = $naver->scrape( URI->new($url) ); for my $page (@{$res->{links}}) { print "$page\n"; } }
■アドベントカレンダーのページからブログのURLを引っ張ってくるコード
use URI; use Web::Scraper; use HTTP::Lite; use strict; use warnings; our $URL_REGREP = '(?:http|https)://(?:[a-zA-Z0-9-;/?|:@&=+$,_.!~*\'%#]+)'; our $BLACKLIST = '.*io[\/]?\z|.*\.jp[\/]?\z|.*\.com[\/]?\z|.*\.net[\/]?\z|.*partake.*|.*twitter\.com\/.*|.*atnd.*|.*zusaar.*|.*aiit.*|.*worksap.*|.*qiita.*|.*adventar.*|.*atmarkit.*|.*r-project.*|http:\/\/www\.cygwin\.com\/|http:\/\/b\.hatena\.ne\.jp\/entry\/|.*github\.com\/|http:\/\/increments\.co\.jp|https:\/\/mixpanel\.com\/f\/partner|http:\/\/kobitoapp\.com|.*google\.co.*|.*wikipedia\.com.*|.*colorschemedesigner.*|.*wonderfl.*'; our $QIITA = 'http://qiita.com/items.*'; our $EndPoint = 'http://api.b.st-hatena.com/entry.count'; my $file = shift; my @advent_urls; my $web = scraper { process 'a', 'links[]' => '@href'; }; sub get_links { my ($url, $BLACK, $WHITE) = @_; my @links; my $res = $web->scrape( URI->new($url) ); for my $page (@{$res->{links}}) { if ($WHITE) { if ($page =~ /($URL_REGREP)/o && ($page !~ /($BLACK)/ || $page =~ /($WHITE)/)) { push(@links, $1); } } else { if ($page =~ /($URL_REGREP)/o && $page !~ /($BLACK)/) { push(@links, $1); } } } return @links; } sub get_numofhatebu { my ($url) = @_; my $http = new HTTP::Lite; my $req = $http->request($EndPoint.'?url='.$url) or die "Unable to get document: $!"; if ($http->body()) { return $http->body(); } else { return 0; } } open( my $fh, "<", $file) or die "Cannot open $file: $!"; while (my $line = readline $fh) { chomp $line; my @links = &get_links($line, $BLACKLIST, $QIITA); for my $link (@links) { my $num = &get_numofhatebu($link); print "|[$line:title]|[$link:title]|$num|\n"; if ($link =~ /($QIITA)/o) { my $NEW_BLACK = $BLACKLIST.'|'.$QIITA; my @qiita_links = &get_links($link, $NEW_BLACK); for my $qiita_link (@qiita_links) { my $qiita_num = &get_numofhatebu($qiita_link); print "|[$line:title]|[$qiita_link:title]|$qiita_num|\n"; } } } }
戦略
スクレイピングモジュールはPerlのWWW::Scraperを利用しています。
最初にnaverにまとめられていたAdvent Calendarのまとめ記事からアドベントカレンダーの募集ページだけを収集します。その後、それぞれのページに対して再度スクレイピングして、今度はブログの記事のURLだけを収集し、はてブ数をはてブAPIから取得してコンソールに表示します。
もともと、atnd、partake、qiita、adventar等、アドベントカレンダーの募集ページの種類が多く、最初は真面目にHTML構文解析してたんですが、途中からさじを投げて "ズル" をすることにしました。"ズル"、というのはaタグのhref属性にあるURLしか見ないことにして、正規表現でURLだと判定されたあと、ブラックリストによって必要/不要を選別することにしたのです。トップレベルドメインだけのリンクやtwitter、google等の明らかにブログではないリンクはブラックリストに入れて無視し、それ以外をひとまず収集。トップ50位のランキングを作った後で、それでもブラックリストを抜けて入ってしまった間違ったページは見て省く、という戦略にしました。最終的には人力です。。。
それにしてもこれだけあると募集ページをどこに作るかだけでも迷ってしまいそうですね。スクレイピングしていた側からすると、adventarが一番楽でした(リンクが少ないので)。atndやconnpass、partakeだと募集ページによってもページ構造がまちまちなので、スクレイピングしにくかったです。atnd, connpass等の募集ページで表組みするのも面倒だと思うので、adventarで募集するのもアリではないでしょうか。
あと、Qiitaのアドカレ募集ページでは、Qiitaのitemページから自分のブログにリンクだけ貼って飛ばしているようなケースもあり、itemページだけを収集するのではなく、さらにitemページの内容もスクレイピングする必要がありました。スクレイピングしていた側からすると、せっかくQiitaに書くならQiitaのページにTipsを書けばいいのにとか少し思いました(^^;)。
(ストックされるとちょっと嬉しい気分になりますよ!)
最後に
というわけで、ちょっと遅れた年賀状です。
今年もよろしくお願い致します。