Python で Qiitaの投稿記事に対するView数を取得してみました ー 改訂版（Over100）

## 概要

[この記事](https://qiita.com/turupon/items/99f501a86d911f9304bb) の改訂版です。個人毎に投稿数が100件超えの場合に対応いたしました。

### 実行環境
macOS Ventura 13.0 
python 3.8.12

### 個人トークンの取得

Qiitaアカウントの個人トークンを以下の手順で取得します

1. 個人アカウントでログイン
2. アカウント → 設定 → アプリケーション → 個人用アクセストークン → トークンを発行する  

### 実行プログラム

```python:QiitaAPI_GetView_Over100.py
import time
import argparse
import requests
import json
from tabulate import tabulate
from math import ceil

# メンバー全員の投稿アカウント毎の個人トークンの定義
tokens = {
    # "yamahiro": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    # "Alex-hiro": "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
    'turupon': "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
}


# アカウント毎に投稿した記事のListを取得
def GetPostList():

    # 投稿アカウントでの取得
    cnt = 0
    views = 0
    for (key, token) in zip(tokens.keys(), tokens.values()) :

        # https のヘッダー情報 with 個人トークン
        print("\n ■---■---■ 投稿者：{}".format(key))
        headers = {
            "Authorization": "Bearer " + token
        }

        # https のパラメータ初期情報
        page_cnt = 1
        per_page = 100

        while True :
            # https のパラメータ設定
            params = {
                "page": str(page_cnt),
                "per_page": str(per_page),
            }

            # 個人トークンを利用してのその個人の投稿記事情報の取得
            res1 = requests.get('https://qiita.com/api/v2/authenticated_user/items', params=params, headers=headers)
            jsonlist = json.loads(res1.text)
            
            # 投稿記事毎View数の取得
            c1, c2, c3 = GetView(jsonlist)
            cnt += c1
            views += c2

            # 次のページがあるかどうか？
            if ceil(c3/per_page) > page_cnt :
                page_cnt += 1
            else:
                break
    
    return cnt, views


# 投稿した記事のView数の取得
def GetView(jsonlist):

    # 取得する情報のキーと値の準備
    item_key=['User', 'url', 'page_views_count', 'likes_count', 'created_at', 'updated_at', 'Title']
    item_value=[]

    # 投稿記事毎の情報の取得
    view_cnt  = 0
    items_cnt  = 0
    for item in jsonlist:
        # その記事情報の取得
        # アカウント名、記事URL、View数、いいね数、作成日、更新日、記事タイトル
        item_value.append([item['user']['id'], item['url'], item['page_views_count'], item['likes_count'], item['created_at'], item['updated_at'], item['title']])
        view_cnt += item['page_views_count']

        # items_count の取得（Page数の算出に利用）
        items_cnt = item['user']['items_count']

    # json形式への変換
    rows = [dict(zip(item_key,item)) for item in item_value]

    # 取得情報の表示
    # print("\n ■---■---■ 投稿者：{}\n".format(rec['user']['id']))
    print(tabulate(rows, headers='keys'))
    print("\n   ---> 投稿数：{}".format(len(rows)))
    print("   ---> 閲覧総数：{}\n".format(view_cnt))

    return len(rows), view_cnt, items_cnt


if __name__ == '__main__':    
    parser = argparse.ArgumentParser(description='Qiitaの投稿記事に対するView数を取得する')
    args = parser.parse_args()

    start = time.time()
    cnt, views = GetPostList()
    generate_time = time.time() - start

    print("")
    print("　Qiita Post 総数 : " + str(cnt))
    print("　Qiita View 総数 : " + str(views))
    print("  取得時間:{0}".format(generate_time) + " [sec] \n")
```

### プログラムの実行
 
```
## 実行結果
$ python QiitaAPI_GetView_Over100.py                                          

 ■---■---■ 投稿者：turupon
User     url                                                     page_views_count    likes_count  created_at                 updated_at                 Title
-------  ----------------------------------------------------  ------------------  -------------  -------------------------  -------------------------  ------------------------------------------------------------------------------------------------------------------
turupon  https://qiita.com/turupon/items/575e7592cde829c3642d                 471              0  2022-11-07T16:17:13+09:00  2022-11-07T16:17:13+09:00  Pythonに パラメータとして日付を渡してみました - 第三弾
turupon  https://qiita.com/turupon/items/0a007c4e3efcb64162f4                 484              0  2022-10-26T13:59:12+09:00  2022-10-26T13:59:12+09:00  Pythonで Azure SubscriptionID の請求データをExportしてみました - REST API編

    :
    省略
    ：

turupon  https://qiita.com/turupon/items/91aadafd951a0e330c70                 846              1  2021-08-10T18:46:22+09:00  2021-08-10T18:46:22+09:00  【既存】 Azure Kubernetes Service (AKS) に Helm を使用して既存のアプリケーションをインストールしてみました
turupon  https://qiita.com/turupon/items/f129bab7a989ae9bdf77                 483              1  2021-08-10T18:40:07+09:00  2021-08-10T18:40:07+09:00  【新規】 Azure Kubernetes Service (AKS) に Helm を使用して新規にアプリケーションをインストールしてみました

   ---> 投稿数：100
   ---> 閲覧総数：67187

User     url                                                     page_views_count    likes_count  created_at                 updated_at                 Title
-------  ----------------------------------------------------  ------------------  -------------  -------------------------  -------------------------  -------------------------------------------------------------------------------------------------------------------------------------------------
turupon  https://qiita.com/turupon/items/c8c1b4c3c51caa1b85b2                1697              1  2021-08-10T18:29:59+09:00  2021-08-10T18:29:59+09:00  ローカルの Dockerイメージ を Azure Container Registry（ACR）に プッシュしてみました
turupon  https://qiita.com/turupon/items/2ec254712618065a1d65                 683              1  2021-07-28T13:17:41+09:00  2021-07-28T13:21:49+09:00  docker-compose.yml を kompose convert して Azure Kubernetes Service (AKS) で動かしました

    :
    省略
    ：

turupon  https://qiita.com/turupon/items/e16789a959fc92068c68                 878              0  2020-12-23T23:41:50+09:00  2020-12-24T11:20:53+09:00  オブジェクトストレージ Cloudian/S3 にJSON形式のデータを書き込みしてみます
turupon  https://qiita.com/turupon/items/f458e37f200185843420                 828              0  2020-12-23T11:51:18+09:00  2020-12-24T11:26:42+09:00  オブジェクトストレージ Cloudian/S3 にあるJSON形式のデータから特定のデータを抽出してみます

   ---> 投稿数：46
   ---> 閲覧総数：73086


　Qiita Post 総数 : 146
　Qiita View 総数 : 140273
  取得時間:2.7081291675567627 [sec] 
```

### まとめ

これで各個人の投稿記事の件数が100件を超えても、問題なくView数を確認できるようになりました、、、、、
ただ、Queryパラメータは「/authenticated_user/items」では無効で「/items」時のみ有効のような気がします、、、、、