Qiita API + Elasticsearch + KibanaでQiitaの今を可視化した話


最近Qiitaへの投稿を始めて感じたことは、だいたい投稿してから3日間~1週間くらいはストックして頂けてるなあということです。
そこで3日間とか1週間くらいのスパンでの人気タグを把握できると、より多くの人に読んでもらえる記事を書けるのでは？と考えてやってみました。


## 概要
* Qiita APIの使い方を解説します
* ElasticsearchとKibanaについては説明しません
* Qiita APIから取れる情報を可視化します
* 最近投稿された1000件の記事内での流行タグや投稿が多い時間帯などがわかります
* 最後に可視化した情報からわかることについてのまとめを書きます


## 環境

| 項目 | 内容 |
|:---:|:---:|
|サーバーOS|CentOS6.6|
|Elasticsearch|5.3.1|
|Kibana|4.3.1 |
|Qiita API| v2|
|APIを呼び出す端末| Mac |
|MacのOS| OS X Yosemite|
|Python|2.7.10|


自身のMacからQiita APIを使って投稿データを入手し、それをそのまんま自身の研究室のサーバ上で稼働中のElasticsearchに送信しました。Elasticsearchへと送信したあとはhttp://xxx.xxx.xxx.xxx:5601
(*xxx.xxx.xxx.xxxは研究室サーバのアドレス*)
にアクセスしてKibanaを使ってグラフなどを作成しました。

## Qiita APIの使い方
詳しくは[Qiita API v2 ドキュメント](https://qiita.com/api/v2/docs)にあります。
ドキュメントの中から自身が参考にした項目を列挙していきます。

###エンドポイント
https://qiita.com/api/v2

###認証
ドキュメントにある<b>利用制限</b>に書いてあるように、認証なしの場合1時間に60回ほどqueryを投げることができます。認証をした場合はそれが1000回になるそうですが、よくわからなかったこともあり、今回は認証はなしでやりました。

### 基本的な投稿データの入手方法

```
$ curl -XGET 'https://qiita.com/api/v2/items?page=3&per_page=20'
```
とやると、とりあえず結果が返ってくるかと思います。
このコマンドの意味は3ページ目のデータを20個入手するということになります。
つまり入手できるデータ数はこれだと20であって、3*20ではないことに注意です。

pageとper_pageは自身で決めることが出来ますが、制約条件があります。
以下の表にまとめておきます。

|parameter|最小値|最大値|
|:---:|:---:|:---:|
|page|1|100|
|per_page|20|100|

各ページから100個ずつ投稿データを入手すると最大で10000件の投稿データを入手することが可能ということになります。

## 投稿データ(json形式)をElasticsearchにそのまんま送信するpythonコード

```python:forward_json.py
# coding: utf-8
import json
import requests
from elasticsearch import Elasticsearch

# Elasticsearchをインストール済みのサーバのアドレス
server_address = "xxx.xxx.xxx.xxx"
# インストール済みで標準の設定だとポートは9200
port = str(9200)
# Elasticsearchのインスタンスを生成
es = Elasticsearch("%s:%s" % (server_address, port))
# エンドポイント
endpoint = 'https://qiita.com/api/v2/items'
for p in range(1, 11): # 1ページから10ページまで同様に以下の処理を行う
    payload = {'page': p, 'per_page': '100'} #1ページあたり100個のデータを入手
    r =  requests.get(endpoint, params=payload).json() #結果をjson形式で受け取る
    '''
    #参考までに
    print type(r)
    # => <type 'list'>
    print r[0].keys() 
    # => [u'body', u'group', u'rendered_body', u'url', u'created_at', u'tags', u'updated_at', u'private', u'coediting', u'user', u'title', u'id']
    '''
    for it in r: #結果のリスト内をループ
        # 全データをぶち込む！！
        # 今回はindexをqiitaという名前にしてみました
        es.index(index='qiita', doc_type='qiita', id=it['id'], body=it)

```

server_addressのところにElasticsearchとKibanaがインストールされたサーバのアドレスを書いてください。
このコードを実行すると合計1000件の投稿データがElasticsearchに格納されるはずです。

## Kibanaによる可視化
http//xxx.xxx.xxx.xxx:5601にアクセスしましょう。
1000個の投稿データをQiitaAPIから取ってきてElasticsearchに格納しました。スクショした画像に数字やグラフの説明を赤字で追加したものです。一応ユーザ名は伏せました。

![kibana.png](https://qiita-image-store.s3.amazonaws.com/0/83457/93716ee5-90ef-d3f8-a933-f47d60cad0ac.png "kibana.png")

投稿数がものすごく多くなっている時間帯がありますのでクリックしてみます。
![スクリーンショット 2016-07-19 22.21.25.png](https://qiita-image-store.s3.amazonaws.com/0/83457/ac227933-4056-31d8-2780-d82777ff42e6.png "スクリーンショット 2016-07-19 22.21.25.png")

上の画像の緑丸をクリックするとページが変わります。

![spike.png](https://qiita-image-store.s3.amazonaws.com/0/83457/363985cf-0603-cc91-40ee-aa6da5357b26.png "spike.png")

熱意有るユーザ様が怒涛の投稿したことで、その時間帯の投稿数が多くなったようです。


## 結果のまとめ
+ 1000件の投稿データ内に誰がどれだけ投稿したかがわかる
	+ 現在、熱意を持って投稿している人をフォローするといろいろな情報が手に入るかも 
+ タグ数:1076とあるが、日本語タグがうまく入手できておらず、”学習”というタグが"学", "習"という2つのタグとして捉えられたりしていた。今後の課題
+ ここ1000件の人気タグを以下の表にまとめます。

| 順位 | タグ名 | 投稿数|
|:---:|:---:|:---:|
|1|python|62|
|2|ruby|50|
|3|aoj|49|
|4|javascript|49|
|5|c|45|
|6|ios |41 |
|7|swift |38 |
|8|php |38 |
|9|java |33 |
|10|linux |29 |

という結果になりました！
やはりプログラミング系のタグが多いですね！
本当はタグのストック数ランキングが知りたかったんですが、ストック数を投稿データから入手するのは認証を行わない状態だと難しかったのでやめました。時間があるときにチャレンジしたいと思います。
今回、pythonタグをつけた投稿が多いことがわかったので、今後もpythonタグをつけれるような投稿をしたいと思います。