Steam データ活用

Steam公式Web APIの使い方【GetAppList/同時接続/実績/ニュース】Python最小サンプル

この記事でできること:Steamの公式Web APIを使って、AppIDの解決同時接続(CCU)実績の到達率/スキーマニュースをPythonで取得する最小手順をまとめます。前回の Step1: AppIDの見つけ方 から続く実装編です。

全体像や注意点は Steamガイド(入口ページ) を参照してください。

対象エンドポイントと認証の要点

目的エンドポイントAPIキーメモ
全アプリ一覧(AppID解決の起点)ISteamApps/GetAppList不要レスポンスが大きい→キャッシュ推奨
同時接続(現在値)ISteamUserStats/GetNumberOfCurrentPlayers不要スナップショット。履歴は自前で取得
実績の到達率(グローバル)ISteamUserStats/GetGlobalAchievementPercentagesForApp不要各実績の解除率%
実績・統計のスキーマISteamUserStats/GetSchemaForGame必要な場合あり実績名/説明/アイコンURLなどの定義
ニュース(パッチ/お知らせ)ISteamNews/GetNewsForApp不要タイトル・URL等

キーが必要な場面では ?key=YOUR_STEAM_WEB_API_KEY を付与(.envや環境変数で管理推奨)。

クイックスタート(Python最小クライアント)

requestsのみ・依存最小の単一ファイル

import os, json, time, difflib, requests
from pathlib import Path

BASE = "https://api.steampowered.com"
API_KEY = os.getenv("STEAM_WEB_API_KEY")  # 必要な場合のみ付与

def _get(url, params=None, timeout=30):
    params = dict(params or {})
    if API_KEY and "key" not in params:
        # 必須のときだけ付ける想定。不要なら無視される
        params["key"] = API_KEY
    for i in range(3):
        try:
            return requests.get(url, params=params, timeout=timeout)
        except requests.RequestException:
            if i == 2: raise
            time.sleep(0.8 * (i+1))

# 1) 全アプリ一覧(キャッシュ)
def get_applist(cache="applist.json"):
    p = Path(cache)
    if p.exists() and p.stat().st_size > 0:
        return json.loads(p.read_text(encoding="utf-8"))
    url = f"{BASE}/ISteamApps/GetAppList/v2/"
    r = _get(url).json()
    apps = r["applist"]["apps"]
    p.write_text(json.dumps(apps, ensure_ascii=False), encoding="utf-8")
    return apps

# 2) 名前→AppID(あいまい一致)
def resolve_appid_by_name(name, apps=None, n=5):
    apps = apps or get_applist()
    names = [a["name"] for a in apps if a.get("name")]
    cands = difflib.get_close_matches(name, names, n=n, cutoff=0.6)
    out = []
    for c in cands:
        appid = next(a["appid"] for a in apps if a.get("name")==c)
        out.append((c, appid))
    return out

# 3) 同時接続(現在値)
def get_ccu(appid:int):
    url = f"{BASE}/ISteamUserStats/GetNumberOfCurrentPlayers/v1/"
    r = _get(url, {"appid": appid}).json()
    return r.get("response", {}).get("player_count")

# 4) 実績の到達率(グローバル)
def get_global_achievement_rates(appid:int):
    url = f"{BASE}/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/"
    r = _get(url, {"gameid": appid}).json()
    return r.get("achievementpercentages", {}).get("achievements", [])

# 5) 実績スキーマ(名称/説明/アイコンURL等)
def get_schema_for_game(appid:int):
    url = f"{BASE}/ISteamUserStats/GetSchemaForGame/v2/"
    r = _get(url, {"appid": appid}).json()
    return r.get("game", {})

# 6) ニュース
def get_news(appid:int, count=3, maxlength=300):
    url = f"{BASE}/ISteamNews/GetNewsForApp/v2/"
    r = _get(url, {"appid": appid, "count": count, "maxlength": maxlength}).json()
    return r.get("appnews", {}).get("newsitems", [])

if __name__ == "__main__":
    apps = get_applist()
    name = "HoloCure"
    cands = resolve_appid_by_name(name, apps)
    print("candidates:", cands[:3])
    if cands:
        appid = cands[0][1]
        print("ccu:", get_ccu(appid))
        print("achv_rates(sample):", get_global_achievement_rates(appid)[:3])
        schema = get_schema_for_game(appid)
        print("achv_total:", len(schema.get("availableGameStats", {}).get("achievements", [])))
        news = get_news(appid)
        print([n["title"] for n in news])

この段階では AppIDの見つけ方 も合わせてご確認ください(DLC/バンドル誤選択の回避)。

ユースケース別の実装パターン

A. CCUを複数タイトルで一括取得(瞬間スナップショット)

APPIDS = [570, 730, 1172470]  # Dota2, CS2, Apex等の例
rows = []
for aid in APPIDS:
    rows.append({"appid": aid, "ccu": get_ccu(aid), "ts": int(time.time())})
print(rows)
# → 自前DB/CSVに追記していくと、のちほど時系列可視化に使えます

B. 実績の「解除率トップ3」を見て難易度の雰囲気を掴む

rates = get_global_achievement_rates(appid)
top3 = sorted(rates, key=lambda x: -x.get("percent", 0))[:3]
for a in top3:
    print(a["name"], a["percent"])

C. 実績スキーマからアイコンURLを取得(記事素材に)

schema = get_schema_for_game(appid)
ach = schema.get("availableGameStats", {}).get("achievements", [])
print(ach[0]["displayName"], ach[0]["icon"])  # icon / icongray

D. ニュースをカード表示用に整形

news = get_news(appid, count=5, maxlength=220)
cards = [{"title": n["title"], "url": n["url"], "date": n.get("date")} for n in news]
print(cards)

エラー処理・レート制限・キャッシュ設計

  • リトライ/タイムアウト:ネットワーク例外時は指数バックオフで再試行。上の _get() のようにラップ関数化。
  • キャッシュ:GetAppList はサイズが大きい。JSON保存して定期的に刷新(例:日次)。
  • 間引き:CCUは5〜10分間隔のポーリングが現実的(のちほど CCUの自前収集と可視化 で詳述)。
  • 堅牢化:レスポンススキーマの存在確認(get(..., {}))とNoneガードで落ちにくく。
  • キー管理:必要な場面では環境変数/設定ファイルに保持(appdetails など非公開仕様APIとの差別も明記)。

この先に進む(関連How-to)

  1. 【How-to】価格・タグ・発売情報を取る(Storefront appdetails)
  2. 【How-to】レビュー本文の取得と要約(appreviews)
  3. 【How-to】同時接続の自前収集と可視化(時系列)
  4. 【How-to】推定オーナー数とタグ集計(SteamSpy)

入口に戻る:Steamガイド / 前の記事:AppIDを見つける5つの方法

免責:本記事は公開情報の整理を目的としています。仕様や挙動は予告なく変わる可能性があります。利用規約・法令・引用ルールを遵守の上ご利用ください。

-Steam, データ活用
-, , , , , ,