Use Steam Game Reviews & Playtime Extractor with Python
Pull Steam customer reviews for any game by URL or name, with thumbs up/down verdicts, reviewer playtime, helpfulness votes, and language filters.
1. Choose the data you need
Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.
2. Prepare a source-based input
This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.
{
"appIds": [],
"gameNames": [],
"helpfulWithinDays": 30,
"includeGameDetails": false,
"includeOffTopic": false,
"language": "all",
"maxGames": 0,
"maxPlaytimeHours": 0,
"maxReviews": 3,
"minPlaytimeHours": 0,
"mode": "reviews",
"purchaseType": "all",
"reviewType": "all",
"sortBy": "recent",
"startUrls": [
{
"url": "https://store.steampowered.com/app/1174180/Red_Dead_Redemption_2/"
}
],
"steamDeckOnly": false,
"useReviewQuality": true
}
Download input.example.json and save your reviewed copy as input.json.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | required | reviews = one row per review; gameSummary = one row per game with metadata and overall score. |
appIds | array | optional | Numeric app IDs, store URLs, community review URLs, or old appreviews URLs. Example: 1174180 or https://store.steampowered.com/app/1174180/ |
startUrls | array | optional | Steam store page URLs for the games to scrape. Merged with appIds. |
gameNames | array | optional | Search Steam by name. An exact case-insensitive title match is preferred over the first search result. |
maxReviews | integer | optional | Reviews to collect per game. Use 0 for every matching review (hard safety cap 1,000,000 per game). |
maxGames | integer | optional | Cap the merged game list. Use 0 for no cap. |
reviewType | string | optional | Filter reviews by recommendation verdict. |
language | string | optional | Steam language code for review text. Select All Languages to include every language. |
sortBy | string | optional | recent and updated walk the full history; helpful is a ranked sample inside the helpfulness window; funny is also ranked and not exhaustive. |
helpfulWithinDays | integer | optional | Only for sortBy=helpful: rank reviews from the last 1-365 days. Use recent for full history. |
purchaseType | string | optional | Whether the reviewer acquired the game through Steam, outside Steam, or either. |
minPlaytimeHours | integer | optional | Minimum hours played at the time of review. Use 0 for no minimum. |
maxPlaytimeHours | integer | optional | Maximum hours played at the time of review. Use 0 for no maximum. |
steamDeckOnly | boolean | optional | Only reviews written while playing primarily on a Steam Deck. |
includeOffTopic | boolean | optional | Include reviews Steam hides as off-topic review-bomb activity. Off by default, matching the store. |
useReviewQuality | boolean | optional | Only for sortBy=helpful: rank low-quality reviews lower. |
reviewsFromDate | string | optional | Include reviews created on or after this UTC date. |
reviewsToDate | string | optional | Include reviews created on or before this UTC date. |
includeGameDetails | boolean | optional | mode=reviews: attach game metadata, price and overall review summary to every review row. |
3. Start an Actor run
Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.
Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.
import json
import os
import urllib.request
# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
actor_input = json.load(stream)
token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
"https://api.apify.com/v2/acts/KcRtpVrqTcmshwJGE/runs?timeout=120&maxTotalChargeUsd=0.50",
data=json.dumps(actor_input).encode("utf-8"),
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.
4. Inspect the actual results
Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.
Steam review rows with reviewer profile, playtime, votes, hardware and flags, plus per-game metadata and overall score summaries.
Questions before you run
Which inputs are required?
The published required fields are mode
What does this guide verify?
The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.
What if the run request times out?
Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.
Generated from source build GxuUpYbrzkiWxwZa1 and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.