Skip to content

Instantly share code, notes, and snippets.

@sakarie9
Last active March 21, 2024 10:24
Show Gist options
  • Save sakarie9/85587359e2c99d0096173a325ff61698 to your computer and use it in GitHub Desktop.
Save sakarie9/85587359e2c99d0096173a325ff61698 to your computer and use it in GitHub Desktop.
好友库存比较器
from typing import Dict, List
import xml.etree.ElementTree as ET
from dataclasses import dataclass
import urllib.request
import urllib.parse
import re
import json
# 填写个人资料链接中的最后一段
# 例如 https://steamcommunity.com/profiles/76561145141919810 中的 76561145141919810
# 或者 https://steamcommunity.com/id/abcdefg 中的 abcdefg
# 主用户名
USER_MAIN = ["abcdefg"]
# 要比较的好友用户名
USERS = ["user1", "user2", "user3"]
@dataclass
class Game:
appID: int
name: str
storeLink: str
def to_dict(self):
return {"appID": self.appID, "name": self.name, "storeLink": self.storeLink}
@classmethod
def from_dict(cls, data):
return cls(**data)
@dataclass
class User:
userID: str
userName: str
games: List[Game]
def to_dict(self):
return {
"userID": self.userID,
"userName": self.userName,
"games": [game.to_dict() for game in self.games],
}
@classmethod
def from_dict(cls, data):
games = [Game.from_dict(game_data) for game_data in data["games"]]
return cls(data["userID"], data["userName"], games)
Users: Dict[str, User] = {}
def get_api_url(userID):
API_BASE = "https://steamcommunity.com/"
API_BASE_SUFFIX = "/games?tab=all&xml=1"
if re.match(r"([^\/][0-9]{16,})", userID):
return API_BASE + "profiles/" + userID + API_BASE_SUFFIX
else:
return API_BASE + "id/" + userID + API_BASE_SUFFIX
def save_cache(user: User):
with open(f"{user.userID}.json", "w", encoding="utf-8") as f:
json.dump(user.to_dict(), f, ensure_ascii=False, indent=4)
def load_cache(userID):
try:
with open(f"{userID}.json", "r", encoding="utf-8") as f:
user_data = json.load(f)
return User.from_dict(user_data)
except:
return None
for user in USER_MAIN + USERS:
print(f"开始加载 {user}")
_user = User(user, "", [])
_user_cache = load_cache(user)
if _user_cache is not None:
_user = _user_cache
else:
user_api_url = get_api_url(user)
# print(f"请求地址:{user_api_url}")
with urllib.request.urlopen(user_api_url) as response:
xml_string = response.read().decode("utf-8")
# 解析XML字符串
root = ET.fromstring(xml_string)
# 提取用户名
_user.userName = root.find("steamID").text
games = root.findall(".//game")
if len(games) == 0:
print(f"没有找到游戏信息,跳过 {user}")
USERS.remove(user)
continue
# 提取appID和name
for game in root.findall(".//game"):
app_id = int(game.find("appID").text)
name = game.find("name").text
store_link = game.find("storeLink").text
# print("appID:", app_id)
# print("name:", name)
_user.games.append(Game(app_id, name, store_link))
save_cache(_user)
Users[user] = _user
set_main_games = {game.appID for user in USER_MAIN for game in Users[user].games}
set_others_games = {game.appID for user in USERS for game in Users[user].games}
print()
print(f"主账号拥有的游戏共 {len(set_main_games)} 个")
duplicated_games = set_main_games & set_others_games
# print(f"共同拥有的游戏:{duplicated_games}")
print(f"共同拥有的游戏共 {len(duplicated_games)} 个")
main_minus_others = set_main_games - set_others_games
# print(f"主账号拥有的游戏,但没有在其他账号拥有:{main_minus_others}")
print(f"主账号拥有的游戏,但没有在其他账号拥有,共 {len(main_minus_others)} 个")
others_minus_main = set_others_games - set_main_games
# print(f"其他账号拥有的游戏,但没有在主账号拥有:{others_minus_main}")
print(f"其他账号拥有的游戏,但没有在主账号拥有,共 {len(others_minus_main)} 个")
# print(Users)
for user in USERS:
print()
print(f"用户:{Users[user].userName} / {user}")
set_games = {game.appID for game in Users[user].games}
print(f"用户拥有的游戏共 {len(set_games)} 个")
duplicated_games = set_main_games & set_games
# print(f"共同拥有的游戏:{duplicated_games}")
print(f"共同拥有的游戏共 {len(duplicated_games)} 个")
main_minus_others = set_main_games - set_games
# print(f"主账号拥有的游戏,但没有在此账号拥有:{main_minus_others}")
print(f"主账号拥有的游戏,但没有在此账号拥有,共 {len(main_minus_others)} 个")
others_minus_main = set_games - set_main_games
# print(f"此账号拥有的游戏,但没有在主账号拥有:{others_minus_main}")
print(f"此账号拥有的游戏,但没有在主账号拥有,共 {len(others_minus_main)} 个")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment