QiitaのAPIを使って集計結果をExcelへ出力する。

# はじめに
自分のQiita記事のview数など集計したく、Qiitaで提供されているAPIをPythonで制御してみた。Excelで下表みたいな感じに出力されることを目標とする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/ad9cc687-650e-29c4-e4a6-e0fa998446ac.png)

**Qiita API**

https://qiita.com/api/v2/docs

# 目次
+ [Qiita APIとは](#qiita-apiとは)
+ [PythonでQiita APIを使う](#pythonでqiita-apiを使う)

## Qiita APIとは
+ Qiita APIはHTTPのメソッドでアクセスする。対応しているメソッドはGET、POST、PUT、PATCH、DELETEの5種類。APIでやり取りするデータのフォーマットはJSON。今回はデータ収集のためにAPIを使うので、GETメソッドを使う。

HTTPメソッド|内容
---|---
GET|データの要求。
POST|データの送信。
PUT|データの更新。
PATCH|データの部分更新。
DELETE|データの削除。

+ GETメソッドの場合はアクセストークンがなくても、1時間60回まではリクエストを受け付けてくれる。上限を超えるアクセス、または、POST、PUT、PATCH、DELETEのメソッドを使う場合は、アクセストークンを取得する必要がある。また、GETメソッドでも本人しか見れないViews数はアクセストークンがないと取得できなかった。アクセストークンはQiitaの **[設定]→[アプリケーション]→[個人用アクセストークン]** で取得できる。
　
+ GETメソッドでパラメータを指定する場合はURIクエリで指定する。URIクエリは```?```の区切り文字から始まる。指定するパラメータが複数ある場合```&```でつなげる。Google検索するときにURLに```?```や```&```の文字が出てくるが、それがURIクエリ。例えばkey1にval1、key2にval2を指定したい場合は```?key1=val1&key2=val2```となる。URIクエリで、```page```(ページ数)と```per_page```(ページあたりの要素数)を指定して、GETメソッドで取得するデータ数を指定する。```?page=5&per_page=20```とすれば、ページあたり20のデータの5ページ目を取得する。
　
+ GETメソッドのAPIは何種類かあるが集計では下記3点を使いそう。

　API|内容
 ---|---
 GET /api/v2/tags/:tag_id/items|```:tag_id```にtagの文字列を指定するとそのtagに合致する記事のデータを取得できる。
 GET /api/v2/users/:user_id/items|```:user_id```にユーザIDの文字列を指定するとそのユーザIDに合致する記事のデータを取得できる。
 GET /api/v2/uses/:user_id|```:user_id```にユーザIDの文字列を指定するとそのユーザIDに合致したユーザ情報を取得できる。

GET(***/items)で取得したデータには下記のようなものがある。

データ|内容
---|---
user_id|ユーザのID
description|ユーザの自己紹介文
items_count|ユーザの記事数
followees_count|ユーザがフォローしているユーザ数
followers_count|ユーザがフォローされているユーザ数
id|記事のID
url|記事のURL
title|記事のタイトル
tags|記事のタグ一覧
stocks_count|記事のストック数
likes_count|記事のいいね数
created_at|記事の作成日時
updated_at|記事の最終更新日時
body|記事の本文
page_views_count|記事の閲覧数(アクセストークンで承認必要。)


+ GETの例。下記のとすれば「tagがPythonで、1ページ(ページあたり5個)分を取得する。」となり、JSON形式でデータがレスポンスされることを確認できる。
> https://qiita.com/api/v2/tags/Python/items?page=1&per_page=5

[戻る](#目次)

## PythonでQiita APIを使う
Qiita APIへのアクセスには、```requests```と```json```のライブラリを使用する。jsonライブラリを使うと JSON形式⇔Pythonの辞書の相互変換ができる。
+ **辞書形式** = json.loads(**JSON形式**)
+ **JSON形式** = json.dumps(**辞書形式**)


```python:qiitaapi_test.py
import requests
import json

# GET
# https://qiita.com/api/v2/tags/Python/items?page=1&per_page=5
qiita_res = requests.get('https://qiita.com/api/v2/tags/Python/items', params = {"page":"1", "per_page":"5"})

#JSONデータを辞書型へ変換
json_data = json.loads(qiita_res.text)

# 1記事づつprint()
for i,d  in enumerate(json_data):
	print(f'-----\n{i:02d}\n-----\n{d["title"]=}\n{d["likes_count"]=}\n{d["stocks_count"]=}')
	tags=[]
	for t in d["tags"]:
		tags.append(t["name"])
	print(f'{tags=}')

# -----
# 0X
# -----
# d["title"]=<記事のタイトル>
# d["likes_count"]=<いいね数>
# d["stocks_count"]=<ストック数>
# tags=[<タグのリスト>]
```

## 自分の記事をExcelファイルに出力する
views含め取得する場合は、アクセストークンで承認が必要。アクセストークンの設定は、GETのリクエストヘッダでアクセストークンを設定する。
Opnepyxlの使い方は👉 [OpenPyXLでExcelファイル読み書き。](https://qiita.com/tapitapi/items/cdeb7a97ed0add7201b5)

```python:qiitaapi_xlsx.py
import requests
import json
import openpyxl as px
from datetime import datetime
from tqdm import tqdm

user = input('ユーザ名:')
token = input('アクセストークン:')

#userの記事数確認
qiita_res = requests.get('https://qiita.com/api/v2/users/'+user)
print(qiita_res)
user_info = json.loads(qiita_res.text)["items_count"]

# 記事数を100ずつに分けて処理
json_data=[]
for i in tqdm(range((user_info+100-1)//100)):
	if token !='':
		qiita_res = requests.get('https://qiita.com/api/v2/users/'+user+'/items', params = {"page":f'{(i+1):d}', "per_page":"100"}, headers= { "Authorization": "Bearer "+token})
	else:
		qiita_res = requests.get('https://qiita.com/api/v2/users/'+user+'/items', params = {"page":f'{(i+1):d}', "per_page":"100"})
	
	#json_dataのリストに追加
	json_data.append(json.loads(qiita_res.text))
	

#Excelファイル「Qiita記事集計.xlsx」出力なければ新規作成して出力。
try:
	wb = px.load_workbook('Qiita記事集計.xlsx')
except:
	wb = px.Workbook()

#シート名を 「user_yymmdd_hhmmss」に設定
wb.create_sheet( user+'_'+datetime.now().strftime('%y%m%d_%H%M%S') , index=0)
ws = wb.active


# ヘッダ
ws.cell(1,1).value = "No"
ws.cell(1,2).value = "タイトル"
ws.cell(1,3).value = "url"
ws.cell(1,4).value = "作成日"
ws.cell(1,5).value = "更新日"
ws.cell(1,6).value = "views"
ws.cell(1,7).value = "いいね"
ws.cell(1,8).value = "ストック"
ws.cell(1,9).value = "tag"

# 1行1記事づつ
nunmber=1
for i in range(len(json_data)):
	for d  in json_data[i]:
		ws.cell(nunmber+1,1).value = nunmber
		ws.cell(nunmber+1,2).value = d["title"]
		ws.cell(nunmber+1,3).value = d["url"]
		ws.cell(nunmber+1,4).value = datetime.fromisoformat(d["created_at"]).strftime('%Y/%m/%d')
		ws.cell(nunmber+1,5).value = datetime.fromisoformat(d["updated_at"]).strftime('%Y/%m/%d')
		ws.cell(nunmber+1,6).value = d["page_views_count"]
		ws.cell(nunmber+1,7).value = d["likes_count"]
		ws.cell(nunmber+1,8).value = d["stocks_count"]
		tags=''
		for t in d["tags"]:
			tags=tags+t["name"]+","
		ws.cell(nunmber+1,9).value = tags
		nunmber+=1

#ExcleファイルSave
wb.save('Qiita記事集計.xlsx')

```
👆を実行するとExcelで下表みたいな感じに出力される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299802/ad9cc687-650e-29c4-e4a6-e0fa998446ac.png)
[戻る](#目次)

以上