Qiitaの記事情報をAPIで取得しCSVに書き出す

# 1. はじめに
Python3でQiitaの記事情報をAPIで取得しCSVに書き出す2種類のスクリプトを作成したので覚書です。

- Qiitaの記事情報1万件分をCSVに書き出すスクリプト
- 指定した期間内に作成されたQiitaの記事情報をCSVに書き出すスクリプト

# 2. Qiitaの記事情報1万件分をCSVに書き出す

Qiitaの記事情報を最新1万件分取得し、PandasでCSVに出力します。
Qiita APIは以下のような仕様になっているので、仕様にあわせてスクリプトを書いていきます。

- pageの最大値は100
- per_pageの最大値は100

Qiita APIで取得できる記事情報は、[JSONのサンプルページ](https://qiita.com/api/v2/items)や、[公式ドキュメント](https://qiita.com/api/v2/docs#%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97)で確認できます。
Qiitaのアクセストークンは[アクセストークン発行ページ](https://qiita.com/settings/tokens/new)から取得しましょう。

## サンプルコード
```python
import http.client
import json
import pandas as pd

h = {'Authorization': 'Bearer <Qiitaのアクセストークン>'}
conn = http.client.HTTPSConnection("qiita.com")
url = "/api/v2/items?"

for i in range(100):
    i += 1
    # Qiita APIで記事情報を取得
    page = "page=" + str(i)
    conn.request("GET", url + page + "&per_page=100", headers=h)
    res = conn.getresponse()
    print(res.status, res.reason)
    data = res.read().decode("utf-8")
    # CSVに出力
    df = pd.read_json(data)
    df.to_csv("qiita.csv", columns=[
        'likes_count', # いいね数
        'created_at', # 作成日時
        'title', # 記事タイトル
        'url' # 記事URL
        ], mode='a', header=False, index=False)
```

# 3. 指定した期間内に作成されたQiitaの記事情報をCSVに書き出す

先ほどのコードで1万件の記事情報を取得してみましたが、何かしらの分析をしたいと思うと、最新の1万件だけではなく指定した期間内に作成された全てのQiita記事を取得したくなってきました。

1万件のデータをみてみると1ヶ月弱で1万件の投稿数になるようです。

そこで、[こちらの記事:Qiitaの記事データをQiita API, Scrapyで収集](https://qiita.com/nkmk/items/fbac13cd05b80334eb2b)を参考にさせていただきながら、指定した期間内に作成されたQiita記事情報をCSVに書き出すスクリプトを作りました。

## サンプルコードの処理の流れ

処理の流れについては、前述の参考記事と同じなので引用させていただきます🙇‍♂️

> GET /api/v2/itemsでは1ページあたり最大100件で最大100ページ、最大で合計10000件のデータを取得でき> る。1回のリクエストで得られるのは100件分で、ページ番号のパラメータpageをカウントアップさせてリクエストを繰り返し、すべての検索結果を取得する。

> 10000件を超えた分のデータは取得できないので、結果件数が10000件に収まるように半月ずつ日時をずらしていく。

このようにして取得した情報をCSVに書き出していきます。

## サンプルコード
以下、サンプルコードです。

```python
import http.client
import json
import pandas as pd
import math

h = {'Authorization': 'Bearer <Qiitaのアクセストークン>'}
conn = http.client.HTTPSConnection("qiita.com")
url = "/api/v2/items?"

# この期間に作成されたQiitaの記事情報を取得
start = '2019-04-15'
end = '2019-06-30'

# 半月ごとの日付をリスト化
date_list = [d.strftime('%Y-%m-%d') for d in pd.date_range(start, end, freq='SM')]
start_list = date_list[:-1]
end_list = date_list[1:]

# カウント用変数
num = 0
p = 0

# start_listの配列の数だけ繰り返し処理
for i in start_list:
    num += 1
    # 日付のリストから検索の開始日と終了日を取り出す
    start_date =  start_list[num - 1]
    end_date = end_list[num - 1]
    query = "&query=created:>" + start_date  + "+created:<" + end_date
    # 検索で指定した期間内に作成された記事数を取得
    conn.request("GET",  url + query, headers=h)
    res = conn.getresponse()
    res.read()
    print(res.status, res.reason)
    total_count = int(res.headers['Total-Count'])
    # 取得した記事数をもとにリクエスト回数を算出
    page_count = math.ceil(total_count / 100)
    print(start_date + "から" + end_date + "までのデータを取得します...")
    print("この期間に作成されたデータを取得するのに必要なリクエスト回数は" + str(page_count) + "回です")
    # データを取得しCSVに書き出す
    for p in range(page_count):
        p += 1
        page = "page=" + str(p)
        conn.request("GET", url + page + query, headers=h)
        res = conn.getresponse()
        print(res.status, res.reason)
        data = res.read().decode("utf-8")
        df = pd.read_json(data)
        df.to_csv("qiita2.csv", columns=[
            'likes_count', 
            'created_at',
            'title',
            'url'
            ], mode='a', header=False, index=False)
        print(str(p) + "/" + str(page_count) + "完了")
```

# 4. おわりに
Pandasがとても便利でした。