【Python】投稿した全記事の閲覧数を取得する

# はじめに

[いいね順で取得する](https://qiita.com/riekure/items/166abfefed095fefe00a)記事を書いたので、その続きとして、今回は閲覧数順です。

# 動作環境

- Windows 10
- Python3.7(Anaconda)

# コードを書く前にやること

Qiita の個人用のアクセストークンを取得してください。

1. https://qiita.com/settings/applications にアクセス（Qiita にログイン済前提）
2. 画面下にある ``新しいトークンを発行する`` を押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233011/4cc2f190-9996-cedd-6aff-fc44d2af85f0.png)
3. ``アクセストークンの説明`` には使用用途などを入力、 ``スコープ`` は ``read_qiita`` を選択した状態で、``発行する`` を押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233011/7eb026d7-9372-2c68-fccb-7a77823f474e.png)
4. 英数字の文字列が表示されるので、コピーしておく。（<font color="Red">**個人情報なので取り扱い注意！**</font>）

# コード

``XXXXXXXXXXXXXXXXXXX`` の部分を発行したアクセストークンに置き換えてください。

```python
import http.client
import requests
import json
import math

CONN = http.client.HTTPSConnection('qiita.com', 443)
USER_ID = 'riekure'
PER_PAGE = 20
URL = 'https://qiita.com/api/v2/authenticated_user/items'
HEADERS = {"content-type": "application/json", "Authorization": "Bearer XXXXXXXXXXXXXXXXXXX"}

class Api:
    # リクエスト結果をJSON形式で返す
    @staticmethod
    def request(http, url) :
        CONN.request(http, url)
        res = CONN.getresponse()
        data = res.read().decode('utf-8')
        return json.loads(data)

    # 投稿数とからページ番号を計算する
    @staticmethod
    def page_count(items_count) :
        return math.floor(items_count / PER_PAGE) + 1

# 投稿数を取得
items_count = Api.request('GET', '/api/v2/users/' + USER_ID)['items_count']
page = Api.page_count(items_count)

# 投稿記事を全て取得
all_article = {}
for i in range(page) :
    res = requests.get(URL + '?page=' + str(i+1), headers=HEADERS)
    list = res.json()
    for item in list :
        item_id = item['id']
        title = item['title']
        url = 'https://qiita.com/api/v2/items/' + item_id
        res = requests.get(url, headers=HEADERS)
        json = res.json()
        page_views_count = json['page_views_count']
        all_article.setdefault(title, page_views_count)

# 閲覧数の降順にソート
# items() を使用するので tuple になる
tuple_items = sorted(all_article.items(), key=lambda x:x[1], reverse=True)
print(all_article)

# markdown の表形式で表示
print('| 記事タイトル | 閲覧数 |')
print('|------------|--------------|')
for title, count in tuple_items:
    print('| ' + title + ' | ' + str(count) + ' |')
```

# 実行結果

2020年6月28日現在

| 記事タイトル | 閲覧数 |
|------------|--------------|
| Java 8 LocalDateTimeの型変換のあれこれ(String, java.util.Date) | 57161 |
| 【Oracle】テーブルのカラム情報をSQLで取得する方法 | 31390 |
| Javaでファイルをバイト配列に変換する方法 | 27834 |
| git revertの基本的な使い方 | 25794 |
| [Windows 10] 矢印キーに指を伸ばすエンジニアはザコ！とバカにされた（Change KeyとAutoHotkeyの導入） | 24472 |
| MyBatisのSQLで不等号の比較演算子を使う | 22104 |
| UnityでVisual Studio Codeを使用できるようにするまでの手順 | 21498 |
| ログインできないユーザでコマンドを実行する方法＋おまけ | 15843 |
| 【Java】StringBuilderの末尾から指定した文字数分を削除する | 15558 |
| Oracle SQLでDB接続中のセッションを特定＆強制終了(KILL) | 15035 |
| 【Java】 (list == null list.size() == 0)でNULL／空チェックしている事が気に入らない | 14769 |
| [Java] ファイル書き込みは何を使えばいいのか | 12379 |
| SimpleDateFormatとDateTimeFormatterの違いってなんだ？？ | 11016 |
| 【Unity】Standard AssetsがImport Packageに表示されていないときの対処方法 | 10817 |
| Javaで英数記号・ひらがな・カタカナ・JIS第一／第二水準漢字以外をエラーにするチェック処理を実装してみた | 10685 |
| 条件式が複数ある三項演算子に混乱した話 | 10414 |
| AWS認定ソリューションアーキテクトアソシエイト(SAA)不合格体験記 | 10263 |
| 10ヶ月勉強してもAWS認定ソリューションアーキテクト-アソシエイト-に合格できないので、勉強方法を振り返る | 9579 |
| [初心者]AWSを月数百円くらいの範囲で使っていると思ったら、2000円くらい請求された話 | 8374 |
| [MyBatis]大量データをマッピングするときはCursorを使おう | 8049 |
| JavaプログラマがPythonを勉強してみた。(型について） | 6873 |
| Windows10のノートPC内蔵キーボードはJIS配列、Bluetooth接続のキーボードはUS配列にする設定方法 | 6566 |
| 特定のポート番号を使用しているプロセスの見つけ方 | 6412 |
| (Java7以降限定)オブジェクトはObjects.equalsで比較してほしい | 5907 |
| Oracle SQL(11g)でMySQLのLIMIT OFFSET句を再現したい | 5880 |
| [Unity]"Can't add script behavior XXXX.The script needs to derive from MonoBehaviour"の改善方法4つ | 5810 |
| 【Unity】Unity-Chan!（ユニティちゃん）でCS0234エラーが発生したときの調査結果と解決方法 | 5159 |
| Unity + Visual Studio CommunityでC#をデバッグ実行する | 5154 |
| Amazon Linux 2でmysql-serverがインストールできないときの対処方法 | 4797 |
| 下位10%のダメなエンジニアにだけ解けないパズルを解いた結果、下位10%のダメなエンジニアだと判明した | 4416 |
| 1年かけてAWS認定ソリューションアーキテクト-アソシエイト-に合格できたので、勉強法を振り返る | 4357 |
| 【Unity】UnityEditor.BuildPlayerWindow+BuildMethodExceptionが発生してAndroidビルドできないときの対処方法 | 4098 |
| 【VSCode】言語ごとにインデント幅、タブとスペースどちらを使うか設定する | 3509 |
| EclipseからIntelliJ IDEAに移行する人のためのショートカット比較(Windows) | 3459 |
| 【Unity】Windows 10で起動時に応答なしになるとき | 3445 |
| 【Unity】Application.LoadLevelは非推奨になっていました | 3335 |
| Aurora(MySQL)でCREATE VIEWしたらエラーが出た | 3214 |
| JavaプログラマがPythonを勉強してみた。(関数(メソッド)について） | 3046 |
| AWS認定ソリューションアーキテクトアソシエイトを合格するまで更新するのをやめないッ！ | 2927 |
| THETA Web API v2.1 を curl コマンドで実行する方法 | 2844 |
| クソコード量産プロジェクトを撲滅するためのESLint導入物語 | 2808 |
| Oculus RiftはSurface Book 2で動かせないから気をつけて！ | 2706 |
| 【Unity】プロジェクトをOculus Go用にビルドするまでに個人的に詰まったところまとめ | 2680 |
| 【Unity】コンポーネントの有効化/無効化をボタン押下で切り替える | 2481 |
| 表で対策するAWS 認定ソリューションアーキテクト - アソシエイト(SAA) ※ 随時更新 | 2467 |
| JavaプログラマがPythonを勉強してみた。(for, if, while文) | 2360 |
| .bash_profileの設定を間違えて、どんなコマンドも"command not found"になってしまったときの解決方法 | 2242 |
| 【Unity】git addしたときのopen("Temp/UnityLockfile"): Permission deniedの原因と対処方法 | 2018 |
| 特定のファイルをrmコマンドなどで削除できないようにする方法(chattr、lsattrコマンド) | 1815 |
| 下位20%のダメなエンジニアにだけ解けないパズルを解いた | 1467 |
| [Java]過去の自分が作成した機能をjava.io.FileからNIO.2で書き直し | 1398 |
| 【Git】fatal: protocol error: bad line length character: usag の解消方法 | 1389 |
| ChromeでAWS Cloud9に接続できないときの対処方法 | 1362 |
| 【Unity】Unity Editorかスマホ実機か判別して処理を分ける | 1350 |
| [Java 8]コーディングテストで使えるアルファベット順、文字列長順のソート方法 | 1349 |
| [Java 8]コーディングテストで使える標準入力をリストまたは配列に変換するまで | 1348 |
| JavaプログラマがPythonを勉強してみた。(デコレータについて） | 1325 |
| [Python] Qiita APIを使って投稿一覧を取得する + 2018年の振り返り | 1305 |
| AWS Innovate Online Conference 「試験対策セッション1：回復性の高いアーキテクチャを設計する」をまとめてみた | 1063 |
| ほとんどのエンジニアには解けるパズル３を解けませんでした | 1033 |
| AWS Innovate Online Conference 「試験対策セッション5：運用上の優秀性（オペレーショナル・エクセレンス）を備えたアーキテクチャを定義する」をまとめてみた | 858 |
| 【Ruby】コーディングテストで使える？標準入力から値を受け取る方法 | 801 |
| AWS Innovate Online Conference 「試験対策セッション4：コスト最適化アーキテクチャを設計する」をまとめてみた | 788 |
| 【Unity】非同期処理を理解する〜コルーチン編〜 | 713 |
| AWS Innovate Online Conference 「試験対策セッション2：パフォーマンスに優れたアーキテクチャを定義する」をまとめてみた | 645 |
| AWS Innovate Online Conference 「試験対策セッション3：セキュアなアプリケーションおよびアーキテクチャを規定する」をまとめてみた | 644 |
| 【Ruby】Ruby初心者がよく使うと思う配列のメソッド | 564 |
| 【Unity】非同期処理を理解する〜async/await編〜 | 463 |
| 【Ruby】二次元配列の宣言を間違えて、要素の変更が想定通りにできなかった原因と反省 | 448 |
| 【Unity】Unity Hub から Unity インストールするときに「不完全または破損したダウンロードファイル」と出たときの対処方法 | 421 |
| 【Katalon Studio】デフォルトのブラウザを変更する方法 | 395 |
| 【Katalon Studio】ダークテーマ（黒背景）にする方法 | 390 |
| マイページからいいね（LGTM）順が消えたので Qiita API 使って取得する | 286 |
| 【Slack】Slack API を使用してメッセージを飛ばすまでの手順 | 158 |
| 時間がない人のためのスクラム開発用語集 | 98 |

限定共有記事も含まれるようなので、その点は注意してください。

# 終わりに

Qiita から卒業したいんですが、移行先が見つかりません。