Steam データ活用

SteamのAppIDを見つける5つの方法【URL/検索/API/Pythonバッチ】

この記事でできること:Steamでデータ取得を始める前段として、AppID(数値)を確実に特定する方法をまとめます。URLからの即判定、名前からの公式APIによる照合、appdetails を使った最終確認、さらに Pythonでの一括解決(CSVバッチ) まで、実務フローで解説します。

このガイドは Steamガイド(入口ページ) の「Step1: AppID取得」に対応しています。

そもそもAppIDとは?

AppIDはSteamで各アプリ(ゲーム・DLC・ソフト等)に割り当てられた一意の数値IDです。レビュー取得(/appreviews)、ストア情報(/api/appdetails)、同時接続(GetNumberOfCurrentPlayers)など、ほぼすべての取得でキーとして使います。

  • ゲーム本体:type=game
  • DLC:type=dlc
  • サウンドトラック等:type=music など

注意:記事・分析の対象が「ゲーム本体」かどうかを、後述の appdetails で検証しましょう(DLC/バンドルを誤って選ばない)。

方法1:ストアURLから直取り(最短)

ストアURLが分かっていれば、https://store.steampowered.com/app/730/...太字部分がAppIDです。記事からの引用や検索結果でURLを見つけたら、これが最速。 Pythonワンライナー(URL → AppID抽出)

import re
def appid_from_url(url: str):
    m = re.search(r"/app/(\\d+)/", url)
    return int(m.group(1)) if m else None
print(appid_from_url("https://store.steampowered.com/app/730/Counter-Strike_2/"))  # 730

方法2:公式APIの全アプリ一覧(ISteamApps)から名前検索

ゲーム名しか分からないときは、公式の全アプリ一覧を取得してローカルで名前マッチさせます。スペル差や表記揺れに備えてあいまい一致が便利。 最小コード(名前 → 候補AppID)

import requests, difflib

def load_applist():
    url = "https://api.steampowered.com/ISteamApps/GetAppList/v2/"
    return requests.get(url, timeout=60).json()["applist"]["apps"]

def find_appid_by_name(name: str, apps: list[dict], n=5):
    names = [a["name"] for a in apps if a["name"]]
    cands = difflib.get_close_matches(name, names, n=n, cutoff=0.6)
    return [(c, next(a["appid"] for a in apps if a["name"]==c)) for c in cands]

apps = load_applist()
print(find_appid_by_name("HoloCure", apps))  # 例: [('HoloCure - Save the Fans!', 2420510)]

ポイント:正式名に近い候補を複数出す→ 次の「方法3」で型(game/dlc)や発売日を確認して確定。

方法3:appdetails で最終確認(型/発売日/価格など)

候補のAppIDは appdetails(非公開仕様のストアAPI)で型が game か発売日価格/無料対応OSタグ などを確認し、対象が本体かを見極めます。 最小コード(AppID → メタ確認)

import requests, json

def appdetails(appid: int, cc="jp", lang="japanese"):
    url = "https://store.steampowered.com/api/appdetails"
    r = requests.get(url, params={"appids": appid, "cc": cc, "l": lang}, timeout=30).json()
    data = r.get(str(appid), {}).get("data")
    return data

meta = appdetails(2420510)
print(meta["name"], meta["type"], meta["release_date"]["date"])
print(meta.get("price_overview", {}))

非公開仕様のため将来変更の可能性に注意。実装はタイムアウト・リトライ・バリデーションを入れるのが実務的です。

方法4:名前からの自動解決関数(あいまい一致 → appdetails検証)

方法2と3を統合し、名前→AppID→型検証を一発で返す関数にしておくと再利用が効きます。DLC/サントラの誤選択を防ぐため、type=="game" を既定でフィルタ。 コピペ用(Python)

import requests, difflib

def resolve_appid(name: str, require_game=True, cc="jp", lang="japanese"):
    apps = requests.get("https://api.steampowered.com/ISteamApps/GetAppList/v2/", timeout=60).json()["applist"]["apps"]
    names = [a["name"] for a in apps if a["name"]]
    cand = difflib.get_close_matches(name, names, n=1, cutoff=0.6)
    if not cand: 
        return None, None
    appid = next(a["appid"] for a in apps if a["name"] == cand[0])
    data = requests.get("https://store.steampowered.com/api/appdetails",
                        params={"appids": appid, "cc": cc, "l": lang}, timeout=30).json().get(str(appid), {}).get("data")
    if not data:
        return appid, None
    if require_game and data.get("type") != "game":
        return None, data  # 見つかったがゲーム本体ではない
    return appid, data

appid, meta = resolve_appid("HoloCure")
print(appid, meta and meta.get("name"), meta and meta.get("type"))

方法5:CSVバッチ(複数タイトルを一括解決)

記事量産や比較分析では、タイトルリストをCSVで一括解決するのが効率的です。 names.csv → results.csv(Python)

"""
names.csv(UTF-8, ヘッダー行あり)
name
HoloCure
Palworld
...
"""
import csv, time

def batch_resolve(input_csv="names.csv", output_csv="results.csv"):
    apps = requests.get("https://api.steampowered.com/ISteamApps/GetAppList/v2/", timeout=60).json()["applist"]["apps"]
    names = [a["name"] for a in apps if a["name"]]
    with open(input_csv, encoding="utf-8") as fin, open(output_csv, "w", newline="", encoding="utf-8") as fout:
        reader = csv.DictReader(fin)
        writer = csv.DictWriter(fout, fieldnames=["query","matched_name","appid","type","release_date"])
        writer.writeheader()
        for row in reader:
            q = (row.get("name") or "").strip()
            if not q: 
                continue
            cand = difflib.get_close_matches(q, names, n=1, cutoff=0.6)
            if not cand:
                writer.writerow({"query": q})
                continue
            appid = next(a["appid"] for a in apps if a["name"] == cand[0])
            data = requests.get("https://store.steampowered.com/api/appdetails",
                                params={"appids": appid, "cc":"jp", "l":"japanese"}, timeout=30).json().get(str(appid), {}).get("data") or {}
            writer.writerow({
                "query": q,
                "matched_name": data.get("name", cand[0]),
                "appid": appid,
                "type": data.get("type"),
                "release_date": (data.get("release_date") or {}).get("date")
            })
            time.sleep(0.3)  # マナー
    print("saved:", output_csv)

batch_resolve()

よくある落とし穴と対処

  • DLC/サントラを拾ってしまうappdetailstypegame を確認。記事テンプレでは game以外は除外
  • 表記揺れ:記号・サブタイトル違いで一致しない場合は、複数候補を出して人工確認。英語名で試すのも有効。
  • 別プラットフォーム版:一部ツール/ソフトは typesoftware。記事目的に合うか確認。
  • レート制限:短時間に連打しない。タイムアウト・リトライ・スリープを実装。
  • キャッシュGetAppList はサイズが大きいのでローカルにキャッシュして再利用。

次のステップ

  1. 【How-to】公式Web APIの使い方(GetAppList / 同接 / 実績)
  2. 【How-to】appdetailsでストア情報を取る
  3. 【How-to】appreviewsでレビュー本文を取る
  4. 【How-to】同時接続の自前収集と可視化
  5. 【How-to】SteamSpyの推定値の扱い

入口に戻る:Steamガイド

免責とポリシー:
appdetails/appreviews は公式ドキュメント外のエンドポイントを利用します。将来の仕様変更により挙動が変わる可能性があります。利用規約・法令・引用ルールを遵守の上でご利用ください。

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