Steam データ活用

Steam同時接続数を自前収集して可視化する方法|CCUをPythonで定期取得

2025年10月17日

この記事では、Steam公式Web APIの GetNumberOfCurrentPlayers を使って、Steamゲームの同時接続数(CCU)を自前で定期収集し、CSV保存・日次集計・移動平均・可視化まで行う方法を解説します。

Steam公式Web APIで取得できる同時接続数は、取得した時点のスナップショットです。過去推移やピーク、アップデート後の変化を見たい場合は、自分で一定間隔で取得し、時系列データとして保存する必要があります。

本記事では、1タイトルの単発取得から、複数タイトルの定期収集、CSVへの追記保存、日次集計、7日移動平均の可視化までをPythonで実装します。

この記事でできること

  • Steamの同時接続数(CCU)をPythonで取得する
  • 複数タイトルのCCUをまとめて取得する
  • 取得時刻とAppIDごとにCSVへ追記保存する
  • 定期実行を前提にした収集スクリプトを作る
  • CCUを日次集計する
  • 7日移動平均で推移を見やすくする
  • レビュー分析でCCUをどう活用するか理解する

想定読者

  • Steamゲームの同時接続数を自分で記録したい方
  • レビュー件数や評価推移とCCUを比較したい方
  • アップデートやセール後のプレイヤー数変化を見たい方
  • Steam公式Web APIの取得結果を時系列データ化したい方
  • Pythonで簡単なデータ収集パイプラインを作りたい方

CCUとは

CCUは Concurrent Users の略で、同時接続ユーザー数を意味します。Steamでは、指定したAppIDについて、現在プレイ中の人数をAPIから取得できます。

ただし、APIで取得できるのは「取得した瞬間の値」です。Steam上で過去の履歴をまとめて取得できるわけではないため、推移を分析したい場合は定期的に取得して保存しておく必要があります。

項目内容
取得できる値取得時点の現在プレイヤー数
履歴取得API単体では過去履歴をまとめて取得できない
分析方法定期取得して時系列データとして保存する
主な用途アップデート後の反応、セール影響、レビュー変化との比較

事前準備

この記事では、SteamのAppIDが分かっている前提で進めます。AppIDの確認方法は以下の記事で解説しています。

SteamのAppIDを確認する方法|URL・検索・API・Python一括取得

また、Steam公式Web APIの基本的な使い方は以下の記事で扱っています。

Steam公式Web APIの使い方|アプリ一覧・同時接続・実績・ニュースをPythonで取得

使用ライブラリ

HTTPリクエストには requests、集計と可視化には pandasplotly を使います。

pip install -U requests pandas plotly

1タイトルのCCUを単発取得する

まずは、1つのAppIDを指定して現在の同時接続数を取得します。

import requests


def get_current_players(appid: int) -> int | None:
    """
    Steam公式Web APIから現在の同時接続数を取得する。
    """
    url = "https://api.steampowered.com/ISteamUserStats/GetNumberOfCurrentPlayers/v1/"

    params = {
        "appid": appid,
    }

    response = requests.get(
        url,
        params=params,
        timeout=30,
    )

    response.raise_for_status()

    data = response.json()

    return data.get("response", {}).get("player_count")


appid = 2246340

player_count = get_current_players(appid)

print("AppID:", appid)
print("現在の同時接続数:", player_count)

player_count が整数で返れば取得成功です。0の場合でも、APIエラーとは限りません。その時点でプレイヤーが少ない、または対象がプレイ中ユーザーの少ないタイトルである可能性があります。

複数タイトルのCCUを取得する

複数タイトルを比較したい場合は、AppIDとタイトル名のリストを用意してループで取得します。

import time
import pandas as pd
from datetime import datetime, timezone


target_apps = [
    {"appid": 2246340, "title": "Monster Hunter Wilds"},
    {"appid": 1446780, "title": "Monster Hunter Rise"},
    {"appid": 582010, "title": "Monster Hunter: World"},
]

rows = []

for app in target_apps:
    appid = app["appid"]

    rows.append({
        "timestamp_utc": datetime.now(timezone.utc).isoformat(),
        "appid": appid,
        "title": app["title"],
        "ccu": get_current_players(appid),
    })

    time.sleep(0.5)

df_ccu = pd.DataFrame(rows)

print(df_ccu)

複数タイトルを取得する場合は、短時間に連続アクセスしすぎないように、タイトルごとに少し間隔を空けています。

CSVへ追記保存する

CCUの推移を見るには、取得結果を毎回保存する必要があります。ここでは、CSVに追記する形で保存します。

from pathlib import Path


def append_ccu_to_csv(
    df: pd.DataFrame,
    output_path: str = "steam_ccu_log.csv",
) -> None:
    """
    CCU取得結果をCSVへ追記保存する。
    """
    path = Path(output_path)
    file_exists = path.exists()

    df.to_csv(
        path,
        mode="a",
        header=not file_exists,
        index=False,
        encoding="utf-8-sig",
    )


append_ccu_to_csv(df_ccu)

print("保存しました。")

この形式で保存しておくと、後から timestamp_utcappidccu を使って時系列分析できます。

収集処理を関数化する

定期実行しやすいように、複数タイトル取得とCSV保存を1つの関数にまとめます。

def collect_ccu_snapshot(
    target_apps: list[dict],
    output_path: str = "steam_ccu_log.csv",
    sleep_sec: float = 0.5,
) -> pd.DataFrame:
    """
    複数タイトルの現在CCUを取得してCSVへ追記保存する。
    """
    timestamp_utc = datetime.now(timezone.utc).isoformat()

    rows = []

    for app in target_apps:
        appid = app["appid"]

        try:
            ccu = get_current_players(appid)
        except Exception as e:
            ccu = None
            error = str(e)
        else:
            error = None

        rows.append({
            "timestamp_utc": timestamp_utc,
            "appid": appid,
            "title": app.get("title"),
            "ccu": ccu,
            "error": error,
        })

        time.sleep(sleep_sec)

    df = pd.DataFrame(rows)

    append_ccu_to_csv(
        df=df,
        output_path=output_path,
    )

    return df


df_latest = collect_ccu_snapshot(
    target_apps=target_apps,
    output_path="steam_ccu_log.csv",
)

print(df_latest)

この関数を定期的に実行すれば、CCUの時系列データを蓄積できます。

5分間隔で収集する場合の考え方

スクリプト内で while True を使って5分おきに実行することもできますが、実運用ではスケジューラ側で定期実行する方法が扱いやすいです。

スクリプトを常時起動し続ける方法よりも、Windowsのタスクスケジューラやcronで定期実行した方が、停止・再開・ログ管理がしやすくなります。

まずは手動実行でCSV追記ができることを確認し、その後で定期実行に切り替える流れが安全です。

簡易的な常時実行版

ローカルで検証するだけなら、以下のように while True で一定間隔ごとに実行できます。

INTERVAL_SEC = 300  # 5分

while True:
    df_latest = collect_ccu_snapshot(
        target_apps=target_apps,
        output_path="steam_ccu_log.csv",
    )

    print(df_latest)

    time.sleep(INTERVAL_SEC)

ただし、この方法はPythonプロセスを起動し続ける必要があります。PCを再起動した場合や、ターミナルを閉じた場合は停止します。

CSVを読み込んで日次集計する

収集したCSVを読み込み、日次平均と日次最大を集計します。

df_log = pd.read_csv(
    "steam_ccu_log.csv",
    parse_dates=["timestamp_utc"],
)

df_log["timestamp_utc"] = pd.to_datetime(
    df_log["timestamp_utc"],
    utc=True,
    errors="coerce",
)

df_log["date_jst"] = (
    df_log["timestamp_utc"]
    .dt.tz_convert("Asia/Tokyo")
    .dt.date
)

daily_ccu = (
    df_log
    .dropna(subset=["ccu"])
    .groupby(["date_jst", "appid", "title"], as_index=False)
    .agg(
        ccu_avg=("ccu", "mean"),
        ccu_peak=("ccu", "max"),
        samples=("ccu", "count"),
    )
)

print(daily_ccu.head())

ccu_avg は日次平均、ccu_peak はその日の最大値、samples は取得できたサンプル数です。取得間隔が乱れた場合は、samples も確認するとデータの信頼性を判断しやすくなります。

7日移動平均を計算する

CCUは曜日や時間帯の影響を受けるため、日次平均だけでは変動が大きく見える場合があります。そこで、7日移動平均を計算します。

daily_ccu = daily_ccu.sort_values(["appid", "date_jst"])

daily_ccu["ccu_avg_ma7"] = (
    daily_ccu
    .groupby("appid")["ccu_avg"]
    .transform(lambda s: s.rolling(7, min_periods=1).mean())
)

daily_ccu["ccu_peak_ma7"] = (
    daily_ccu
    .groupby("appid")["ccu_peak"]
    .transform(lambda s: s.rolling(7, min_periods=1).mean())
)

print(daily_ccu.head())

7日移動平均を使うと、曜日による上下をならし、全体的な増減傾向を見やすくできます。

PlotlyでCCU推移を可視化する

最後に、日次平均と7日移動平均をPlotlyで可視化します。

import plotly.express as px


fig = px.line(
    daily_ccu,
    x="date_jst",
    y="ccu_avg",
    color="title",
    title="Steam CCU 日次平均",
    markers=True,
)

fig.update_layout(
    template="plotly_white",
    height=600,
    xaxis_title="日付",
    yaxis_title="同時接続数(日次平均)",
)

fig.show()

7日移動平均を見たい場合は、yccu_avg_ma7 を指定します。

fig_ma7 = px.line(
    daily_ccu,
    x="date_jst",
    y="ccu_avg_ma7",
    color="title",
    title="Steam CCU 7日移動平均",
    markers=True,
)

fig_ma7.update_layout(
    template="plotly_white",
    height=600,
    xaxis_title="日付",
    yaxis_title="同時接続数(7日移動平均)",
)

fig_ma7.show()

必要に応じて、HTMLとして保存することもできます。

fig_ma7.write_html(
    "steam_ccu_ma7.html",
    include_plotlyjs="cdn",
    full_html=True,
)

定期実行する方法

CCUを継続収集するには、スクリプトを定期実行します。ローカルPCで始める場合は、Windowsのタスクスケジューラが使いやすいです。

Windowsの場合

  • タスクスケジューラを開く
  • 新しいタスクを作成する
  • トリガーで5分ごと、10分ごとなどを指定する
  • 操作でPython実行ファイルとスクリプトパスを指定する
  • ログ出力先を決めて、失敗時に気づけるようにする

最初から5分ごとに動かすより、まずは30分ごとや1時間ごとで安定動作を確認してから間隔を短くすると安全です。

macOS / Linuxの場合

macOSやLinuxでは、cronで定期実行できます。

*/10 * * * * /path/to/python /path/to/collect_steam_ccu.py >> /path/to/steam_ccu.log 2>&1

この例では、10分ごとにスクリプトを実行し、ログを steam_ccu.log に追記します。

収集間隔の目安

収集間隔は、目的に応じて決めます。

目的収集間隔の目安補足
ざっくり日次傾向を見る30分〜1時間日次平均や週次傾向なら十分な場合が多い
アップデート直後の反応を見る5〜15分イベント直後の変化を見たい場合
長期で安定運用する10〜30分負荷とデータ量のバランスがよい
多数タイトルを監視する30分以上タイトル数が多いほど間隔を長めにする

常に5分間隔で収集する必要はありません。レビュー分析の補助であれば、10〜30分間隔でも十分なことが多いです。

レビュー分析での活用例

CCUの推移は、Steamレビュー分析と組み合わせると有用です。

見たいこと使い方
アップデート後に人が戻ったかニュースやパッチノートの日付とCCU推移を比較する
低評価増加とプレイヤー数の関係レビュー件数・好評率・CCUを同じ時系列で見る
セール後の定着セール期間後もCCUが維持されているか確認する
大型イベントの効果イベント開始前後のCCUピークや平均値を比較する
長期的な人気推移7日移動平均や月次平均でトレンドを見る

レビュー本文だけを見ると、声の大きい不満が目立つことがあります。CCUと組み合わせると、「不満は多いが人は戻っている」「評価は高いがプレイヤー数は伸びていない」など、別の視点から解釈できます。

取得・運用時の注意点

CCUを自前収集するときは、以下の点に注意してください。

  • 取得値はスナップショット
    取得した瞬間の値であり、一定期間の平均ではありません。
  • 過去データは後から取得できない
    必要な期間は事前に収集しておく必要があります。
  • 収集間隔を短くしすぎない
    過度な短間隔取得は避け、目的に合った間隔にします。
  • 欠損は発生する前提で扱う
    通信失敗やPC停止により欠損が出るため、集計時にサンプル数も確認します。
  • 時刻はUTC保存がおすすめ
    保存時はUTC、表示時にJSTへ変換すると扱いやすいです。
  • 外部サイトの数値と完全一致しない場合がある
    取得タイミングや集計方法の違いにより、SteamDBやSteamChartsの表示と差が出る場合があります。

この方法が向いているケース

この方法は、レビュー分析とあわせてプレイヤー数の変化を確認したい場合に向いています。単発の現在値だけで十分な場合は、Steam公式Web APIの記事で紹介した GetNumberOfCurrentPlayers の最小サンプルだけでも対応できます。

一方で、アップデート前後、セール期間、イベント期間などの変化を追いたい場合は、あらかじめ定期収集しておくことで、後から時系列で比較できるようになります。

次に読む記事

まとめ

この記事では、Steam公式Web APIを使って、同時接続数(CCU)を自前収集し、CSV保存、日次集計、7日移動平均、Plotly可視化まで行う方法を紹介しました。

Steam公式Web APIで取得できるCCUは、取得時点のスナップショットです。過去推移を分析したい場合は、定期的に取得して保存しておく必要があります。

レビュー件数、好評率、レビュー本文、アップデート情報とCCU推移を組み合わせることで、Steamレビュー分析の解釈をより立体的にできます。

-Steam, データ活用