2016年の振り返り
私事ですが、2016年のQiita振り返りをさせていただきます。
2016年に投稿したQiitaの記事は17本、これで18本目になります。
平均すると1カ月に1本以上書いてはいるのですが、時期的にはやはり波がありますね。
ネタのストックがなかったとか DevOps導入指南 執筆のタイミングと被ったとかいうのもあるかもしれませんが、下期は全体的に少なかったです。
1年の中で印象深かったのは、
の記事で、ありがたいことにこれだけで2000を超えるいいね1をいただくことができ、他の記事とあわせて年初に500程度だった総Contributionは現時点で3700を超えるまでになりました。
個人的にこうした数字で見える成果は好きなので、来年もアウトプットを続けるモチベーションになったと思っています。
Contributionの分析
さて、現時点での総Contributionは上の記事1本によるところが大きいのですが、ちょっとContributionの分析をやってみます。
- 総Contribution
- 記事数
- 記事あたりの平均Contribution(平均)
- Top記事によるContribution(Top数)
- Top記事によるContributionが総Contributionに占める割合(Top占有率)
総Contribution | 記事数 | 平均 | Top数 | Top占有率 |
---|---|---|---|---|
3799 | 26 | 146.115 | 2390 | 62.91% |
という感じでした。
やはりTop記事による占有率が半分以上、運の要素があるとはいえ、ぽっと出感が否めません。
継続的によいアウトプットを出しつつ、よりContributionを高めていきたいと思います( 使命感 )
Qiitaレジェンド達はどうか
それではQiitaで 総ContributionのTOP100をひた走るQiitaレジェンド達 はどうなのでしょうか。
まず、Qiitaレジェンドの一覧を得なければなりません。
ありがたいことにランキングサイトを作ってくださった方がいました。たまに見てます^^(病気)。
そういえば現時点で僕は104位でした。もう少しでTOP100入り...!
こちらでTOP1002のユーザを確認することができます。
あとはそれぞれのユーザを確認してちまちま計算すれば大丈夫そうです。
それでは、地道に収集、計算していきたいと思います。
なお、たまたま私は シェル芸人3 を目指しておりますので、地道にワンライナーでの収集、計算にチャレンジします。環境はCentOS 7.2.15114です。
$ for PAGE in $(seq 1 5) ; do for USER in $(curl -s https://qiita-user-ranking.herokuapp.com/?page=${PAGE} | grep -E "第[0-9]*位" -A 1 | grep href | sed -e "s/^.*href=\".*\">\(.*\)<\/a>.*$/\1/g") ; do echo -en "@${USER}\t" ; curl -s http://qiita.com/${USER} | grep Contribution | sed -e "s/^.*<span class=\"userActivityChart_statCount\">\([0-9]*\)<\/span><br \/> <span class=\"userActivityChart_statUnit\">Contribution<\/span>.*<span class=\"userActivityChart_statCount\">\([0-9]*\)<\/span><br \/> <span class=\"userActivityChart_statUnit\">Items<\/span>.*<span class=\"fa fa-like\"><\/span> \([0-9]*\)<\/div>.*<a itemprop=\"url\" href=\"\(.*\)\">\(.*\)<\/a><ul class=\"list-inline userPopularItems_tags tagList\">.*\(itemprop.*\)\{,4\}.*$/\1\t\2\t\3\t\[\5\](http:\/\/qiita.com\4)/g" ; done ; done | awk -F"\t" '{if(NF==5) print "|"NR"|"$1"|"$2"|"$3"|"$2/$3"|"$4"|"$4/$2*100"%|"$5}'
出力がそのままMarkdownの表形式になるようにしたので見出しをつけてペタリ。
やはり上位のQiitaレジェンドは何か1つの記事で稼いだという感じでもなく、Top記事が1000いいねを超えていても占有率は高々20%という感じが大半のようです。
例外的なのは @jacksuzuki さんですかね...。
僕もいいねせずにはいられませんでしたが、 ロシアの天才ハッカーによる【新人エンジニアサバイバルガイド】 が1記事で5000を超えるいいねを集め、 占有率99.8102% というまた違ったレジェンドっぷりを輝かせております。
他に目立つものといえば、全体でもトップの @hirokidaichi さんは平均いいねが1000近く、ある程度数を重ねられている方でこの数値では圧倒的。
他には、 @tukiyo3 さんの 記事数1421 なんてのもすごい数字です。 @tbpgr さんの681でもすごい数字なのにその2倍近いとは恐れ入ります。。。
シェル芸の解説
せっかくなので収集、計算に使ったシェル芸の簡単な解説をしておきます。
- Qiita User RankingからTOP100ユーザ名を抜き出す
- 各ユーザのQiitaトップページを取得する
- Qiitaトップページから「総Contribution」「記事数」「Top数」「Top記事」を抜き出す
- それぞれの値から「平均いいね」「Top占有率」を計算し、出力する
1. Qiita User RankingからTOP100ユーザ名を抜き出す
ランキングページの中身を見ると、
<h2>ランキング一覧</h2>
<p>
第1位
<a href="http://qiita.com/hirokidaichi">hirokidaichi</a>,
30974
</p>
<p>
第2位
<a href="http://qiita.com/jnchito">jnchito</a>,
26930
</p>
<p>
第3位
<a href="http://qiita.com/suin">suin</a>,
20108
</p>
というような感じになっています。そこで、特徴的な「第○位」に着目し、
$ grep -E "第[0-9]*位" -A 1 | grep href | sed -e "s/^.*href=\".*\">\(.*\)<\/a>.*$/\1/g"
の要領でユーザ名を抜き出しています。
欲しいユーザ名は「第○位」の1行下にあるため、 grep -A 1
で出すことにしています。あとはみんな大好き正規表現で抽出しているだけですね。
ランキングページ自体は20件ずつの表示になっているため、
$ for PAGE in $(seq 1 5) ; do curl -s https://qiita-user-ranking.herokuapp.com/?page=${PAGE} ; done
で合計100件分をまわしています。
curl -s
オプションで邪魔なステータスを出ないようにしています。
2. 各ユーザのQiitaトップページを取得する
こちらも簡単です。先ほど取得したユーザ名一覧を使って、
$ for USER in $([ユーザ名一覧]) ; do curl -s http://qiita.com/${USER} ; done
とするだけです。
3. Qiitaトップページから「総Contribution」「記事数」「Top数」「Top記事」を抜き出す
おわかりかと思いますが、ここが一番面倒です。
Qiitaユーザトップのソースを見てもらえばお分かりになるかと思いますが、実はこのページから 得たい情報の全てが1行のソースに存在 しています。
もちろんコードによって生成されていますので、法則性があり正規表現で捕まえられるのですが、ピンポイントで捕まえるのには結構苦労しました。
sed -e "s/^.*<span class=\"userActivityChart_statCount\">\([0-9]*\)<\/span><br \/> <span class=\"userActivityChart_statUnit\">Contribution<\/span>.*<span class=\"userActivityChart_statCount\">\([0-9]*\)<\/span><br \/> <span class=\"userActivityChart_statUnit\">Items<\/span>.*<span class=\"fa fa-like\"><\/span> \([0-9]*\)<\/div>.*<a itemprop=\"url\" href=\"\(.*\)\">\(.*\)<\/a><ul class=\"list-inline userPopularItems_tags tagList\">.*\(itemprop.*\)\{4\}.*$/\1\t\2\t\3\t\[\5\](http:\/\/qiita.com\4)/g"
どこまで行っても正規表現なので、興味がある方はページのソースと正規表現でにらめっこしてみてください。
1つだけ説明を加えておくと、「Top数」「Top記事」を取るのが大変でした。
1行が長いため、色々な部分で .*
のワイルドカード的な表現を使っているのですが、 最長一致 などの都合でなかなか思うように抜き出しができませんでした。
最終的には、Top5記事に対するitempropを手掛かりに、最初の1つにパターンマッチをかけ、残り4つには \(itemprop.*\)\{4\}
を引っ掛けることでTop記事に関する情報だけを抜き出しました。
4. それぞれの値から「平均いいね」「Top占有率」を計算し、出力する
あとは awk
を使った簡単な計算です。
sed
の出力をタブでさせていたので、デリミタをタブにしつつ各行の値を計算して出力しています。
ここでランクが出力されますが、ストリームのレコード番号を格納する NR
で出しています。結構便利。
ちまちま挟んであるパイプはMarkdownでの表にするためですね。
awk -F"\t" '{if(NF==5) print "|"NR"|"$1"|"$2"|"$3"|"$2/$3"|"$4"|"$4/$2*100"%|"$5"|"}'
条件で NF==5
を指定していますが、それはこのあと出てきます。
46位がいない件
お気づきの方もいらっしゃるでしょうか、実は上の表では 46位が欠けています 。
46位にランクされているのは @Qiita さんなのですが、投稿記事数が4でTOP100ユーザの中で唯一「 投稿記事数が5未満 」となっています。
どうして上の表に出てこないかというと、処理説明3のところで、
Top5記事に対するitempropを手掛かりに、最初の1つにパターンマッチをかけ、残り4つには
\(itemprop.*\)\{4\}
を引っ掛ける
と書いていたのですが、投稿記事数が4つしかない @Qiita さんは上記の正規表現で上手く値が取れませんでした。
そのため、 sed
の結果としてフィールド数が足りない状態であるため、最後の awk
で NF==5
の条件をつけることで結果から弾いています。
そもそももっと頭のいい正規表現を書ければ今の方針でもなんとかなったのかと思いますが、15分考えてもいいものが浮かばなかったので諦めました5。
何かいい方法をお持ちの方はぜひご指導をお願いいたしますm(_ _)m
ちなみに @Qiita さんのContributionまわりは下記の感じです。
ランク | ユーザ名 | 総Contribution | 記事数 | 平均いいね | Top数 | Top占有率 | Top記事 |
---|---|---|---|---|---|---|---|
46 | @Qiita | 6743 | 4 | 1685.75 | 5417 | 80.3351% | Markdown記法 チートシート |
チートシートは僕もたいへんお世話になりました。
おわりに
シェル芸たのしい^^
来年は sed
awk
とかメジャーなものだけじゃなく、もっと黒魔術っぽいシェル芸を身に着けたいです。がんばろう。
-
投稿した当時はまだストックによるContribution反映でした。 ↩
-
なお、こちらのサイトの仕様上「サイトにある情報は結構タイムラグがあったりします」とのことなので、実際のTOP100ではない可能性があります。 ↩
-
シェル芸: マウスも使わず、ソースコードも残さず、GUIツールを立ち上げる間もなく、あらゆる調査・計算・テキスト処理をCLI端末へのコマンド入力一撃で終わらすこと。あるいはそのときのコマンド入力のこと。(シェル芸の定義バージョン1.1) ↩
-
GNU bash 4.2.46, GNU sed 4.2.2, GNU Awk 4.0.2でした。 ↩
-
組織アカウントだし、まぁいいかな、なんて...(逃げ) ↩