Stats for owned Steam Games
There are websites out there to analyse your Steam library. But I actually don't want to give the data to someone else. I want a csv of my data to play around with. And building this is actually not that hard.
First we need to get the games from our profile.
All games are listed here https://steamcommunity.com/id/YOUR_STEAM_ID/games/?tab=all.
Then download the HTML. Only the HTML, the images are not important.
The full Python code to convert the HTML file to a csv:
import calendar import csv import re import sys from datetime import datetime from html import unescape months = {name: i for i, name in enumerate(calendar.month_abbr) if name} months["Sept"] = 9 def parse_playtime(raw): m = re.match(r"([\d.]+)\s+minutes", raw) return f"{float(m.group(1)) / 60:.1f} hours" if m else raw def parse_date(s): m = re.match(r"(\d{1,2})\s+(\w+)\s*(\d{4})?", s) if not m or m.group(2) not in months: return s day = int(m.group(1)) month = months[m.group(2)] year = int(m.group(3)) if m.group(3) else datetime.now().year return f"{year}-{month:02d}-{day:02d}" def extract(pattern, text): m = re.search(pattern, text) return m.group(1).strip() if m else "" parts = re.split(r'<img alt="([^"]+)"', sys.stdin.read()) writer = csv.writer(sys.stdout) writer.writerow(["Name", "Playtime", "Last Played", "Achievements"]) for name, rest in zip(parts[1::2], parts[2::2]): if not rest.startswith(' loading="lazy"'): continue played = extract(r"TOTAL PLAYED</span>([^<]+)", rest) last = extract(r"LAST PLAYED</span>([^<]+)", rest) achievements = extract(r"ACHIEVEMENTS</a><span[^>]*>([^<]+)", rest) writer.writerow( [ unescape(name), parse_playtime(played) if played else "", parse_date(last) if last else "", achievements, ] )
The script is called like this: python convert.py < Steam\ Community\ __\ YOURUSER\ __\ Games.html > games.csv.
Some explanations for the code:
First the helper functions.
The parse_playtime function is needed to convert the minutes to hours to have only one decimal number in the Playtime column.
The second function parse_data convert the dates to the one correct date format: ISO 8601.
Steam uses "Sept" for dates instead of "Sep", which is annoying, but can be easily fixed.
And finally the extract function is the multiple times used regex to get the actual values from the HTML.
The for-loop searches for img elements that have an "alt" set.
At first I used the CSS classes but they look generated.
The image will always be there, so this should reliably work for some time in the future.
The last played column can have values like today or yesterday in there. This wasn't important enough for me to actually fix.
The csv looks like this:
Name,Playtime,Last Played,Achievements <game1>,136.8 hours,2020-05-23,60/91 <game2>,92.4 hours,2025-10-06,26/26 <game3>,26.7 hours,2025-03-13,41/44 <game4>,17.2 hours,2023-06-07,10/10
I don't want to leak the games I play, so I redacted the names. And obviously I have a lot more lines in my csv file.
Later I used the csv to build a script that outputs some stats in Markdown. For example this one:
## Games Last Played by Year | Year | Count | | |------|------:|-| | 2013 | 1 | | | 2014 | 3 | ██ | | 2015 | 21 | ███████████████████ | | 2016 | 16 | ███████████████ | | 2017 | 22 | ████████████████████ | | 2018 | 6 | █████ | | 2019 | 8 | ███████ | | 2020 | 26 | ████████████████████████ | | 2021 | 18 | ████████████████ | | 2022 | 22 | ████████████████████ | | 2023 | 26 | ████████████████████████ | | 2024 | 32 | ██████████████████████████████ | | 2025 | 29 | ███████████████████████████ | | 2026 | 12 | ███████████ |
I used the csv to ask Claude what games I should play next. The list Claude returned had no real surprises in there. Now I only have to find the time and mood to actually play them. 😀
