Python实现Steam库存游戏海报下载并组装海报墙的一种解决办法(按游玩时长进行排序)

在周五的闲暇之余,打开我的steam,看我的库存游戏,猛然一个念头油然而生。

能不能直接把我的库存生成一张海报墙,便于跟群友们分享(装逼),于是便写了此篇文章。

一、获取你的steamAPI密钥

  1. 打开网址:https://steamcommunity.com/dev/apikey
  2. 登录你的steam账号
  3. 域名=密钥名称,你自己随便填
  4. 勾选生成密钥并确定。

生成后界面如下图:

切记!保存好你的密钥,避免泄露。接下来我们就要用密钥对海报进行获取。

二、获取你的SteamID(即你个人资料网址的后边一串数字)

  1. 打开你的steam
  2. 点击头像-点击查看我的个人资料

如下图红框位置即为你的SteamID,图中我的就是76561198893327278(欢迎骚扰):

三、下载中文海报并合称为海报墙

  1. 打开你的PyCharm ,新建项目-新建python文件
  2. 复制下列代码到你新建的python文件中,并修改其中的API_KEYSTEAM_ID为你自己的。
  3. 右键运行你的python代码即可,等待控制台输出“拼接完成 → steam_poster_with_hours.jpg

PS:海报保存在你的项目文件夹的covers文件夹下。

import requests
import os
import math
from PIL import Image, ImageDraw, ImageFont

API_KEY = "1234567890"    #修改为你自己的密钥
STEAM_ID = "76561198893327278"  #修改为你自己的SteamID

# 1. 获取游戏数据
url = f"https://api.steampowered.com/IPlayerService/GetOwnedGames/v1/?key={API_KEY}&steamid={STEAM_ID}&include_appinfo=true"
games = requests.get(url).json()["response"]["games"]

# 2. 按游玩时长排序
games = sorted(games, key=lambda g: g.get("playtime_forever", 0), reverse=True)

# 3. 下载封面
folder = "covers"
os.makedirs(folder, exist_ok=True)

langs = ["schinese", "tchinese", ""]  # 优先简中,其次繁中,最后默认

for g in games:
    appid = g["appid"]
    cover_path = os.path.join(folder, f"{appid}.jpg")
    if os.path.exists(cover_path):
        continue

    success = False
    for lang in langs:
        if lang:
            cover_url = f"https://cdn.cloudflare.steamstatic.com/steam/apps/{appid}/library_600x900_{lang}.jpg"
        else:
            cover_url = f"https://cdn.cloudflare.steamstatic.com/steam/apps/{appid}/library_600x900.jpg"
        try:
            r = requests.get(cover_url, timeout=10)
            if r.status_code == 200:
                with open(cover_path, "wb") as f:
                    f.write(r.content)
                success = True
                break
        except Exception as e:
            print(f"下载失败 {appid} {lang}: {e}")

    if not success:
        print(f"找不到 {appid} 的封面")


# 4. 拼接成海报墙(按时长排序)
images = []
playtimes = []  # 存储对应的游玩时长(小时)
playtimesMin = []  # 存储对应的游玩时长(min)

for g in games:
    path = os.path.join(folder, f"{g['appid']}.jpg")
    if os.path.exists(path):
        images.append(Image.open(path))
        playtimes.append(g.get("playtime_forever", 0) // 60)  # 分钟转小时
        playtimesMin.append(g.get("playtime_forever", 0)) # 分钟
# 统一大小
size = (200, 300)
images = [img.resize(size) for img in images]

cols = 10
rows = math.ceil(len(images) / cols)

# 每个格子高度 = 封面 + 文本区
cell_w, cell_h = size[0], size[1] + 40
poster = Image.new("RGB", (cols * cell_w, rows * cell_h), (0, 0, 0))

# 字体(Windows 一般有 Arial;如果报错可以换成 "DejaVuSans.ttf")
try:
    font = ImageFont.truetype("arial.ttf", 20)
except:
    font = ImageFont.load_default()

draw = ImageDraw.Draw(poster)

for i, img in enumerate(images):
    x = (i % cols) * cell_w
    y = (i // cols) * cell_h
    poster.paste(img, (x, y))
    hours = playtimes[i]
    mins = playtimesMin[i]
    if hours != 0:
        text = f"{hours}h"
    else:
        text = f"{mins}min"
    bbox = draw.textbbox((0, 0), text, font=font)
    tw = bbox[2] - bbox[0]
    th = bbox[3] - bbox[1]
    draw.text((x + (cell_w - tw) // 2, y + size[1] + 10), text, font=font, fill=(255, 255, 255))

poster.save("steam_poster_with_hours.jpg")
print("拼接完成 → steam_poster_with_hours.jpg")

给大家看下成品效果,如下图: