0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Qiitaの投稿数やリアクション数を集計する

Last updated at Posted at 2025-03-25

はじめに

特定期間の自身の活動を振り返るため、Qiitaの投稿数やリアクション数を集計するプログラムを作成しました。

コード

pip install pydantic-settings
qiita_count.py
import datetime
from collections import defaultdict

import requests
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    qiita_token: str = Field(..., description="Qiitaのアクセストークン")
    start_month: str = Field(default="1900-01", description="合計期間の開始月")
    end_month: str = Field(default="2100-01", description="合計期間の終了月")

    model_config = SettingsConfigDict(
        env_file=".env",
        case_sensitive=False,
        cli_parse_args=True,
        extra="allow",
    )


def main():
    # 設定の読み込み
    settings = Settings()

    # ここにQiitaのアクセストークンを設定
    ACCESS_TOKEN = settings.qiita_token

    headers = {"Authorization": f"Bearer {ACCESS_TOKEN}"}

    # 認証済みユーザーの投稿を取得するエンドポイント
    url = "https://qiita.com/api/v2/authenticated_user/items"

    items = []
    page = 1
    per_page = 100  # 1ページあたりの取得件数

    # ページネーションに対応してすべての投稿を取得する
    while True:
        params = {"page": page, "per_page": per_page}
        resp = requests.get(url, headers=headers, params=params)
        if resp.status_code != 200:
            print("Error:", resp.text)
            break
        data = resp.json()
        if not data:  # 取得データがなくなったらループ終了
            break
        items.extend(data)
        page += 1

    # 月ごとの投稿数とリアクション数を集計する
    monthly_stats = defaultdict(
        lambda: {
            "post_count": 0,
            "likes_count": 0,
            "stocks_count": 0,
            "page_views_count": 0,
        }
    )
    for item in items:
        created_at = item.get("created_at")
        # 日時文字列をdatetimeオブジェクトに変換
        dt = datetime.datetime.strptime(created_at, "%Y-%m-%dT%H:%M:%S%z")
        month_str = dt.strftime("%Y-%m")
        if settings.start_month <= month_str <= settings.end_month:
            monthly_stats[month_str]["post_count"] += 1
            monthly_stats[month_str]["likes_count"] += item.get("likes_count", 0)
            monthly_stats[month_str]["stocks_count"] += item.get("stocks_count", 0)
            monthly_stats[month_str]["page_views_count"] += item.get(
                "page_views_count", 0
            )

    # 結果の出力
    for month, stats in sorted(monthly_stats.items()):
        print(
            f"{month}: 投稿数: {stats['post_count']}, いいね数: {stats['likes_count']}, ストック数: {stats['stocks_count']}, 閲覧数: {stats['page_views_count']}"
        )

    # 指定された期間の合計を計算
    total_posts = sum(
        monthly_stats[m]["post_count"]
        for m in monthly_stats
        if settings.start_month <= m <= settings.end_month
    )
    total_reactions = sum(
        monthly_stats[m]["likes_count"] + monthly_stats[m]["stocks_count"]
        for m in monthly_stats
        if settings.start_month <= m <= settings.end_month
    )
    total_page_views = sum(
        monthly_stats[m]["page_views_count"]
        for m in monthly_stats
        if settings.start_month <= m <= settings.end_month
    )
    print(f"\n{settings.start_month}から{settings.end_month}の合計:")
    print(f"投稿数: {total_posts}")
    print(f"リアクション数: {total_reactions}")
    print(f"閲覧数: {total_page_views}")


if __name__ == "__main__":
    main()

出力は以下のような感じです。
QIITA_TOKENを環境変数に設定しますstart_month、end_monthで指定した期間の月ごとの数値と合計を出力します。
合計を出力する際、いいね数とストック数はリアクション数としてまとめられます。

% python qiita_count.py --start_month 2024-10 --end_month 2025-03
2024-10: 投稿数: 19, いいね数: 13, ストック数: 4, 閲覧数: 15617
2024-11: 投稿数: 8, いいね数: 9, ストック数: 1, 閲覧数: 6732
2024-12: 投稿数: 6, いいね数: 3, ストック数: 3, 閲覧数: 3802
2025-01: 投稿数: 6, いいね数: 2, ストック数: 3, 閲覧数: 4291
2025-02: 投稿数: 5, いいね数: 1, ストック数: 0, 閲覧数: 1882
2025-03: 投稿数: 7, いいね数: 1, ストック数: 0, 閲覧数: 894

2024-10から2025-03の合計:
投稿数: 51
リアクション数: 40
閲覧数: 33218

解説

設定値の取得

pydantic-settingを使うことで、環境変数またはコマンドライン引数から必要な情報を取得します。両方で指定される場合はコマンドライン引数が優先されます。

class Settings(BaseSettings):
    qiita_token: str = Field(..., description="Qiitaのアクセストークン")
    start_month: str = Field(default="1900-01", description="合計期間の開始月")
    end_month: str = Field(default="2100-01", description="合計期間の終了月")

    model_config = SettingsConfigDict(
        env_file=".env",
        case_sensitive=False,
        cli_parse_args=True,
        extra="allow",
    )

投稿数とリアクション数の取得

QIITA_TOKENの発行元ユーザのすべての投稿を取得し、月単位で合計します。

    # 認証済みユーザーの投稿を取得するエンドポイント
    url = "https://qiita.com/api/v2/authenticated_user/items"

    items = []
    page = 1
    per_page = 100  # 1ページあたりの取得件数

    # ページネーションに対応してすべての投稿を取得する
    while True:
        params = {"page": page, "per_page": per_page}
        resp = requests.get(url, headers=headers, params=params)
        if resp.status_code != 200:
            print("Error:", resp.text)
            break
        data = resp.json()
        if not data:  # 取得データがなくなったらループ終了
            break
        items.extend(data)
        page += 1

    # 月ごとの投稿数とリアクション数を集計する
    monthly_stats = defaultdict(
        lambda: {
            "post_count": 0,
            "likes_count": 0,
            "stocks_count": 0,
            "page_views_count": 0,
        }
    )
    for item in items:
        created_at = item.get("created_at")
        # 日時文字列をdatetimeオブジェクトに変換
        dt = datetime.datetime.strptime(created_at, "%Y-%m-%dT%H:%M:%S%z")
        month_str = dt.strftime("%Y-%m")
        if settings.start_month <= month_str <= settings.end_month:
            monthly_stats[month_str]["post_count"] += 1
            monthly_stats[month_str]["likes_count"] += item.get("likes_count", 0)
            monthly_stats[month_str]["stocks_count"] += item.get("stocks_count", 0)
            monthly_stats[month_str]["page_views_count"] += item.get(
                "page_views_count", 0
            )
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?