はじめに

年があけ、突然昨年自分がどれくらい記事を書いたのか気になりはじめてしまい、本来なら年末くらいに、やってみたくなるような内容の記事となりました。
以前から気になっていたQiitaAPIも叩けたので概ね満足、さっそくハンズオンしていきます。

参考資料

参考リンクには今回作成した大元になる方のハンズオンです。QiitaAPIを利用する部分についてご参考にさせていただきました、なによりお手本があると大変助かり理解も捗りました。

自分の投稿したQiita記事のPV数をAPIで取得する
[多分Python] ちょうど100記事目なので、記事データを引っこ抜いてきて簡単なランキングを作って、コメントしてみる [Pandas]

参考と言うにはおこがましいですが、Qiita公式APIの仕様リンクはも記述しておきます
Qiita Developer公式 Qiita API v2仕様についての説明

構成図

スクリーンショット 2022-01-08 15.26.51.png

ハンズオン

0:事前準備(Qiita_APIで利用するトークンの取得)

1:Qiitaの自分のアイコンを選択して設定を押下する
スクリーンショット 2022-01-08 15.35.17.png
2:『アプリケーション』から『個人用アクセストークン』の『新しくトークンを発行する』を押下する
スクリーンショット 2022-01-08 15.35.35.png
3:『個人用アクセストークン』にトークンが発行されるので、以下APIを利用する際に使用するので任意の場所に保存する
スクリーンショット 2022-01-08 15.35.47.png

1:コードの記述

サンプルコード(コメントアウトで各動作の内容記述あり)

import requests  #リクエスト
import json      #json利用のため使用
import os        #環境変数
from dotenv import load_dotenv #.env利用
load_dotenv()

# 環境変数
Qiita_token = os.getenv('QIITA') #トークン直打ちでも可能

# エンドポイント
endpoint_url = "https://qiita.com/api/v2/authenticated_user/items" # 記事データ取得APIのURL
detail_endpoint = 'https://qiita.com//api/v2/items/' #詳細記事データ取得APIのURL

# Qiita_apiを送る際のheaderとparam
header = {
    "Authorization": "Bearer " + Qiita_token,  #Authorizationヘッダーでアクセストークンを付与
    "content-type": "application/json",# json形式
    "charset": "utf-8" # 文字コード
}

param = {
    "page": "1",# 取得するページ番号
    "per_page": "100"# 上記ページに含まれる要素数(今回で言えば記事の数)
}

# データ取得した項目をリストにする
page_views = [] # リスト

# 記事データ取得APIより、自分の記事IDの取得(page_views_countがNoneのため利用)
def my_article_id_acauisition():
  qiita_info = requests.get(endpoint_url, params=param, headers=header)
  qiita_obj = qiita_info.json() #qiita_objに自分の記事情報を代入

  for item in qiita_obj:#自分の記事情報を利用して、詳細記事データ取得
    detail_endpoint_url = detail_endpoint + item["id"]
    detail_qiita_info = requests.get(detail_endpoint_url, params=param, headers=header)
    detail_qiita_obj = json.loads(detail_qiita_info.text)

    title = item["title"]
    url = item["url"]
    tags = item["tags"]
    created_at = item["created_at"]
    likes_count = item["likes_count"]
    page_views_count = detail_qiita_obj['page_views_count']

    page_views.append({ #リスト化(sortなどの利用を考慮)
      "title": title,
      "url": url,
      "tags": [ tag["name"] for tag in tags ],
      "created_at": created_at,
      "likes_count": likes_count,
      "page_views_count": page_views_count
  })

  for page_view in page_views: #リストにした内容を表示させるための記述
      print(f"""page_view: {page_view['page_views_count']}
    title: {page_view['title']}
    url: {page_view['url']}
    tags: {page_view['tags']}
    likes_count: {page_view['likes_count']}
    created_at: {page_view['created_at']}\n""")

if __name__ == "__main__": #qiita_article_acquisition.pyが呼び出された場合、関数を呼び出す
  my_article_id_acauisition()

2:部分的な説明

2.1 今回利用するライブラリをインストールする

# ライブラリのインポート
import requests  #リクエスト
import json      #json利用のため使用
import os        #環境変数
from dotenv import load_dotenv #.env利用
load_dotenv()

2.2 .envの環境変数を代入する

# 環境変数
Qiita_token = os.getenv('QIITA') #トークン直打ちでも可能

.envファイルをから、load_dotenvでファイルの中身を読み取り『0:事前準備(Qiita_APIで利用するトークンの取得)』で用意したトークンを環境変数として読み込む

.
├── .env
└── qiita_article_acquisition.py

2.3 関数で利用するの変数を代入する

# エンドポイント
endpoint_url = "https://qiita.com/api/v2/authenticated_user/items" # 記事データ取得APIのURL
detail_endpoint = 'https://qiita.com//api/v2/items/' #詳細記事データ取得APIのURL

2.4 Qiita_APIを利用する際にheaderの設定、paramの設定

Qiita APIを呼び出すために『2.2 .envの~』で代入した値を、Authorizationヘッダーでアクセストークンを付与する

# Qiita_apiを送る際のheaderとparam
header = {
    "Authorization": "Bearer " + Qiita_token,  #Authorizationヘッダーでアクセストークンを付与
    "content-type": "application/json",# json形式
    "charset": "utf-8" # 文字コード
}

param = {
    "page": "1",# 取得するページ番号
    "per_page": "100"# 上記ページに含まれる要素数(今回で言えば記事の数)
}

# データ取得した項目をリストにする
page_views = [] # リスト

2.5 my_article_acauisition()関数

# 記事データ取得APIより、自分の記事IDの取得(page_views_countがNoneのため利用)
def my_article_acauisition():
  qiita_info = requests.get(endpoint_url, params=param, headers=header)
  qiita_obj = qiita_info.json() #qiita_objに自分の記事情報を代入

APIドキュメントよりpage_views_countが取得できそうだったのですが、jsonで返ってくる値がNoneだったため調査をする。
詳細記事を利用することでpage_views_countを取得できそうだったので、ここでの動きとしては記事個別に割り振られているIDを取得するための動きをしていると理解する

  for item in qiita_obj:#自分の記事情報を利用して、詳細記事データ取得
    detail_endpoint_url = detail_endpoint + item["id"]
    detail_qiita_info = requests.get(detail_endpoint_url, params=param, headers=header)
    detail_qiita_obj = json.loads(detail_qiita_info.text)

詳細記事のエンドポイントと詳細記事データ(記事個別のID)を併せて、requests.get(detail_endpoint_url, params=param, headers=header)して、json.loads()でJSONファイルを読み込む

    title = item["title"]
    url = item["url"]
    tags = item["tags"]
    created_at = item["created_at"]
    likes_count = item["likes_count"]
    page_views_count = detail_qiita_obj['page_views_count']

JSONより取得した値を代入する。page_views_count = detail_qiita_obj['page_views_count']のみ、取得するリストの場所が他の項目と異なっている

    page_views.append({ #リスト化(sortなどの利用を考慮)
      "title": title,
      "url": url,
      "tags": [ tag["name"] for tag in tags ],
      "created_at": created_at,
      "likes_count": likes_count,
      "page_views_count": page_views_count
  })

取得した値をpage_views = [].appendで要素を追加する。
"tags"は投稿の際に付与したタグの分だけ表示されるので、タグの名称だけを表示できるようにする
今後likes_countが多いものからなどのsort利用を考えて記述、いまのところ無くても差し支えない

  for page_view in page_views: #リストにした内容を表示させるための記述
      print(f"""page_view: {page_view['page_views_count']}
    title: {page_view['title']}
    url: {page_view['url']}
    tags: {page_view['tags']}
    likes_count: {page_view['likes_count']}
    created_at: {page_view['created_at']}\n""")

リストの内容の表示のされ方、今回は前述のsort利用もないので表示のされ方は最新の投稿記事順に表示される

if __name__ == "__main__": #qiita_article_acquisition.pyが呼び出された場合、関数を呼び出す
  my_article_acauisition()

qiita_article_acquisition.pyが呼び出された場合、関数を呼び出すための記述(おまじない的になっているけれど記述)

3:挙動の確認

tetutetu214@mbp 0_Qiita_hanson % python qiita_article_acquisition.py

page_view: 371
    title: APIを利用して場所名の緯度経度から近隣の店舗を表示する構築
    url: https://qiita.com/i3no29/items/2aabb51ca0eb6f08f700
    tags: ['Python', 'api']
    likes_count: 2
    created_at: 2022-01-01T14:02:44+09:00

page_view: 353
    title: 弊社ブログページが更新されたらLINE NotifyによりLINE通知の構築
    url: https://qiita.com/i3no29/items/58f52dc315a6485939bd
    tags: ['Python', 'スクレイピング', 'LineNotify']
    likes_count: 1
    created_at: 2021-12-25T21:24:24+09:00

page_view: 375
    title: 電車遅延情報をスクレイピング(Python)で、LINE NotifyによりLINE通知の構築
    url: https://qiita.com/i3no29/items/c8e9363bd12a61228f82
    tags: ['Python', 'スクレイピング', 'LineNotify']
    likes_count: 0
    created_at: 2021-12-20T07:35:16+09:00

※※※※※※※※※※※※※※※※以下省略※※※※※※※※※※※※※※

さいごに

page_viewなどを見ることが出来るようになると『投稿してやるぞ!』という自分のモチベーションアップにもつながり、意外と構築してみて良かったかなと思いました。なぜpage_views_countが取得できないのかなど、追求しないといけないところもありますが、来週あたりにでも再び手を動かしながらコード理解を深めていきたいと思います。

Last modified: 2022-01-08

Author