はじめに
PythonでQiitaAPIを使って、記事の整理をしてみた。QiitaAPIは下記。
目次
QiitaAPIの概要
- 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は何種類かあるが今回は下記4点を使う。
API | 内容 |
---|---|
GET /api/v2/users/:user_id |
:user_id にユーザIDの文字列を指定するとそのユーザIDに合致した「ユーザ情報」を取得できる。 |
GET /api/v2/users/:user_id/items |
:user_id にユーザIDの文字列を指定するとそのユーザIDに合致する「記事」のデータを取得できる。 |
GET /api/v2/items/:item_id/likes |
:item_id に記事のIDを指定すると、合致する記事の「いいね」のデータを取得できる。 |
GET /api/v2/items/:item_id/stocks |
:item_id にt記事のIDを指定すると、合致する記事の「ストック」のデータを取得できる。 |
- GETの例。下記のとすれば「ユーザIDが[qiita]で、1ページ(ページあたり5個)分を取得する。」となり、JSON形式でデータがレスポンスされることを確認できる。
https://qiita.com/api/v2/users/qiita/items?page=1&per_page=5
- 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 | 記事の閲覧数(アクセストークンで承認必要。) |
- 条件を絞りたい場合は、URIクエリに
query
を使うこともできる。queryは下記参照。
https://help.qiita.com/ja/articles/qiita-search-options
QiitaAPIでデータ取得する例
下記例はqiita_api()
という関数にしてみた。ユーザIDとトークンIDは自分のものを設定する。投稿した記事の各種情報と、各記事に対して「いいね」や「ストック」してくれたユーザのリストを出力する。自分の今まで投稿した記事の情報がリストとして返答される。投稿した記事数によっては、処理に時間がかかるので注意。
関数名 | 引数 | 戻り値 |
---|---|---|
qiita_api(user, token) | user : ユーザID token : トークンID |
記事の情報をリストとして返す。 |
ポイントとしては
- GETで返答するデータを100で1ページとして分割していること。数量が多いとGETしきれないため。
- いいねとストックのユーザリストは別関数
user_list_check()
にしていること。 - likes(いいね)とstockers(ストック)でGETしたときのパラメータが違うので注意。likes(いいね)は2階層になっている。
import requests
import json
import openpyxl as px
from datetime import datetime
import pprint
def qiita_api(user, token):
Ret=[]
#-------------------------------------------------------
#いいね、ストックしてくれたユーザのリスト取得
# items_id : 記事のID
# check_type : likes(いいね) stockers(ストック)
# count : いいね or ストックのユーザ数
# token : トークンID
#-------------------------------------------------------
def user_list_check(items_id, check_type, count, token):
Ret = []
user_list=[]
for i in range((count+100-1)//100):
qiita_res = requests.get(f'https://qiita.com/api/v2/items/{items_id}/{check_type}', params = {'page': f'{(i+1):d}', 'per_page':'100'}, headers= { 'Authorization': f'Bearer {token}'})
# listに格納
user_list.append(json.loads(qiita_res.text))
# ユーザのリストごと処理
for i in range(len(user_list)):
if check_type == 'stockers':
Ret = [u['id'] for u in user_list[i]]
elif check_type == 'likes':
Ret = [u['user']['id'] for u in user_list[i]]
return Ret
# userの記事数確認
qiita_res = requests.get(f'https://qiita.com/api/v2/users/{user}')
items_count = json.loads(qiita_res.text)['items_count']
# 記事を100ずつに分けて取得
post_list=[]
for i in range((items_count+100-1)//100):
qiita_res = requests.get(f'https://qiita.com/api/v2/users/{user}/items', params = {'page': f'{(i+1):d}', 'per_page':'100'}, headers= { 'Authorization': f'Bearer {token}'})
# post_listに格納
post_list.append(json.loads(qiita_res.text))
# 1記事ずつ処理
for i in range(len(post_list)):
for post in post_list[i]:
post_detail={}
post_detail['ID'] = post['id']
post_detail['タイトル'] = post['title']
post_detail['URL'] = post['url']
post_detail['作成日'] = datetime.fromisoformat(post['created_at']).strftime('%Y/%m/%d')
post_detail['更新日'] = datetime.fromisoformat(post['updated_at']).strftime('%Y/%m/%d')
post_detail['VIEW数'] = post['page_views_count']
post_detail['Tag'] = [tag['name'] for tag in post['tags']]
post_detail['いいね数'] = post['likes_count']
post_detail['いいねユーザ'] = user_list_check(post['id'], 'likes', post['likes_count'], token)
post_detail['ストック数'] = post['stocks_count']
post_detail['ストックユーザ'] = user_list_check(post['id'], 'stockers', post['stocks_count'], token)
Ret.append(post_detail)
return Ret
user = input('ユーザ名:')
token = input('アクセストークン:')
pprint.pprint(qiita_api(user, token))
実行結果イメージ。XXXは伏字にしたところ。
[{'ID': '764440297cb9b1302b81',
'Tag': ['Python', 'replace', 'pandas'],
'URL': 'https://qiita.com/tapitapi/items/764440297cb9b1302b81',
'VIEW数': XXX,
'いいねユーザ': [],
'いいね数': 0,
'ストックユーザ': [],
'ストック数': 0,
'タイトル': 'Pandasの要素指定・置換',
'作成日': '2024/10/14',
'更新日': '2024/10/14'},
{'ID': 'fdd86439840dfa96c312',
'Tag': ['Python', 'pandas'],
'URL': 'https://qiita.com/tapitapi/items/fdd86439840dfa96c312',
'VIEW数': XXX,
'いいねユーザ': ['XXX', 'XXX', 'XXX', 'XXX', 'XXX'],
'いいね数': 5,
'ストックユーザ': ['XXX',
'XXX',
'XXX',
'XXX',
'XXX',
'XXX',
'XXX',
'XXX',
'XXX',
'XXX'],
'ストック数': 10,
'タイトル': 'Pandasでよく使う23選',
'作成日': '2024/10/13',
'更新日': '2024/10/13'},
・・・・
参考にした記事
以上