この記事でできること:
サードパーティの SteamSpy API から 推定オーナー数(owners) や タグ投票(tags) を取得し、規模感の把握・ジャンル傾向の可視化・分析の優先度付けに活用する方法をまとめます。
併せて、日次スナップショット保存 → 時系列化の実務テンプレも配布します。
全体像は Steamガイド(入口ページ) を、AppIDの取得は Step1 を参照してください。
SteamSpyとは(要点)
- Steamユーザープロファイルの標本から 統計的に推定 したメトリクスを提供する外部サービス。
- 代表的なエンドポイント:
request=appdetails&appid=<APPID>
、request=all
(全体一覧)など。 - 推定値である点に注意(厳密値ではない)。指標は規模感の目安として使い、意思決定の“第一段”に。
- 同じアプリでも時期により推定が揺れるため、日次で保存して推移を持つ運用が実務的。
取得できる主な項目(抜粋)
キー | 意味 | メモ |
---|---|---|
name , developer , publisher | 基本属性 | 表記揺れあり |
owners | 推定オーナー数(例:200000..500000 ) | 範囲表記。中央値に寄せて数値化する例を後述 |
ccu | 前日ピークCCUの推定 | 瞬間ではなく“日次ピーク”系 |
positive , negative , userscore , score_rank | レビュー集計系指標 | “傾向”の参考に |
average_forever , median_forever | 累計平均/中央値プレイ時間(分) | やり込み度の目安 |
price , initialprice , discount | 価格・割引 | 時点のスナップショット |
languages , genre | 言語・ジャンル | 文字列 |
tags | タグ名→投票数(辞書) | 人気度/特徴量として有用 |
クイックスタート:Python最小サンプル(requests)
AppID一件の詳細(ownersとtagsを抽出)
import requests
def steamspy_appdetails(appid:int):
url = "https://steamspy.com/api.php"
r = requests.get(url, params={"request":"appdetails", "appid": appid}, timeout=30)
r.raise_for_status()
return r.json()
def owners_to_midpoint(owners_range:str) -> int | None:
# "200000..500000" → 350000 のように中央値に寄せる
try:
lo, hi = owners_range.split("..")
return (int(lo) + int(hi)) // 2
except Exception:
return None
data = steamspy_appdetails(730) # 例:CS2
owners_mid = owners_to_midpoint(data.get("owners",""))
top_tags = sorted((data.get("tags") or {}).items(), key=lambda x: -x[1])[:5]
print("owners(mid):", owners_mid)
print("top tags:", top_tags)
公式ラッパを使う(steamspypi
)
# pip install steamspypi
import steamspypi
def steamspy_appdetails_pi(appid:int):
req = {"request":"appdetails", "appid": appid}
return steamspypi.download(req)
print(steamspy_appdetails_pi(730)["name"])
複数タイトルを一括取得 → DataFrame化
owners中央値と上位タグを列にまとめる
import time, pandas as pd, requests
def fetch_many(appids:list[int], sleep=0.3):
rows = []
for aid in appids:
try:
d = requests.get("https://steamspy.com/api.php",
params={"request":"appdetails","appid":aid},
timeout=30).json()
owners_mid = owners_to_midpoint(d.get("owners",""))
tags = sorted((d.get("tags") or {}).items(), key=lambda x: -x[1])
row = {
"appid": aid,
"name": d.get("name"),
"owners_mid": owners_mid,
"ccu_peak_yday": d.get("ccu"),
"userscore": d.get("userscore"),
"price": d.get("price"),
"discount": d.get("discount"),
"tag_top1": tags[0][0] if len(tags)>0 else None,
"tag_top2": tags[1][0] if len(tags)>1 else None,
"tag_top3": tags[2][0] if len(tags)>2 else None,
}
rows.append(row)
except Exception:
pass
time.sleep(sleep) # マナー
return pd.DataFrame(rows)
df = fetch_many([570, 730, 1172470])
print(df)
日次スナップショットで“推移化”する(実務テンプレ)
毎日1回:owners中央値・前日ピークCCUなどをCSVに追記
"""
config:
APPIDS = 例: [570, 730, 1172470]
実行頻度 = 1日1回(cron/タスクスケジューラ)
"""
import csv, time, requests, datetime as dt
from pathlib import Path
APPIDS = [570, 730, 1172470]
OUT = Path("steamspy_daily.csv")
def today_utc():
return dt.datetime.utcnow().date().isoformat()
def fetch_row(appid:int):
d = requests.get("https://steamspy.com/api.php",
params={"request":"appdetails","appid":appid},
timeout=30).json()
return {
"date_utc": today_utc(),
"appid": appid,
"name": d.get("name"),
"owners_mid": owners_to_midpoint(d.get("owners","")),
"owners_raw": d.get("owners"),
"ccu_peak_yday": d.get("ccu"),
"userscore": d.get("userscore"),
"price": d.get("price"),
"discount": d.get("discount")
}
def append_daily():
is_new = not OUT.exists()
with OUT.open("a", newline="", encoding="utf-8") as f:
fields = ["date_utc","appid","name","owners_mid","owners_raw","ccu_peak_yday","userscore","price","discount"]
w = csv.DictWriter(f, fieldnames=fields)
if is_new: w.writeheader()
for aid in APPIDS:
row = fetch_row(aid)
w.writerow(row)
time.sleep(0.4)
print("appended:", OUT)
append_daily()
これで owners/ccuの“時系列” が作れます。CCUの“瞬間値”は公式APIで収集するため、Step5 と合わせて設計してください。
タグ人気の読み方と活用
tags
は「タグ名 → 投票数」の辞書です。人気の定義は複数あります:
- 票数ベース:投票数の多いタグほど“強く結びつく特徴”。
- 規模ウェイト:
owners_mid
と組み合わせ、票数 × owners_mid
で規模×紐づきの強さを近似。 - 勢い:CCU時系列 と組み合わせ、「最近CCUの高いタイトルに多いタグ」を抽出。
単純な「タグ×規模ウェイト」ランキング例(擬似)
import pandas as pd
# df_apps: fetch_many() の結果に tags 辞書も含めてある前提(適宜改修)
def tag_weight_table(appids:list[int]):
rows = []
for aid in appids:
d = steamspy_appdetails(aid)
owners_mid = owners_to_midpoint(d.get("owners",""))
for tag, votes in (d.get("tags") or {}).items():
rows.append({"appid": aid, "tag": tag, "votes": votes, "owners_mid": owners_mid,
"weight": (owners_mid or 0) * votes})
return (pd.DataFrame(rows)
.groupby("tag", as_index=False)
.agg(votes_sum=("votes","sum"), owners_sum=("owners_mid","sum"), weight_sum=("weight","sum"))
.sort_values("weight_sum", ascending=False))
tbl = tag_weight_table([570, 730, 1172470])
print(tbl.head(10))
まずは 票数ベースの集計から始め、必要に応じて 規模ウェイトや 直近CCU を掛け合わせると“今強いタグ”が見えてきます。
注意点・ベストプラクティス(重要)
- 推定である前提:owners/ccuを厳密値として扱わない。順位・規模感・優先度付けの材料に。
- 時系列の自前保有:APIはスナップショット中心。日次保存で推移を作るのが実務。
- 欠損・外れ値:推定が飛ぶ日がある。移動中央値/外れ値除外で可視化の安定度を高める。
- レート&マナー:間隔をあけ、失敗時はリトライ。大規模バッチはスロット分割。
- 解釈の整合:価格やタグの“表記”は appdetails 側と突き合わせて正規化。
ユースケースと導線
- 市場規模のあたり付け:ownersでTAM感を掴む → 深掘りは レビュー要約 と CCU時系列。
- タグ別の勢い:票数×規模×直近CCUで“今熱いタグ”を特定 → 記事企画に。
- 比較テーブル:複数タイトルで owners/ccu/userscore/価格 を横並びに。
この先に進む(関連How-to)
入口に戻る:Steamガイド / これまで:Step1 → Step2 → Step3 → Step4 → Step5
免責とポリシー:
SteamSpyは第三者サービスの推定値を提供します。挙動や仕様は予告なく変わる可能性があります。利用規約・法令・引用ルールを遵守の上でご利用ください。