Steam Reviews Scraper
Pricing
from $0.70 / 1,000 reviews
Steam Reviews Scraper
Steam reviews with the hours the reviewer had actually played. Some scrapers return that field; none compute with it. This weights sentiment by playtime and bands reviewers from drive-by to veteran, so a 12-minute opinion cannot outvote a 500-hour one.
Pricing
from $0.70 / 1,000 reviews
Rating
0.0
(0)
Developer
Datalayer
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
19 days ago
Last modified
Categories
Share
Steam Reviews Scraper — Playtime-Weighted Sentiment
Steam tells you 82% of reviews are positive. It does not tell you that most of those came from people who played for 40 minutes, while the players with 300 hours have turned on the game.
Steam's API carries playtime_at_review — how many hours the reviewer had
actually played when they wrote it. Some scrapers hand it back as a column.
None of them do anything with it. This one does the maths.
What you get that a normal review scraper cannot give you
Weighted sentiment vs raw sentiment. Every review is weighted logarithmically by hours played, so a 12-minute opinion cannot outvote a 500-hour one. The gap between the two numbers is the headline:
| App | Raw % | Weighted % | Shift |
|---|---|---|---|
| Healthy game | 84.0 | 85.1 | +1.1 |
| Game in trouble | 78.0 | 51.4 | −26.6 |
A large negative shift means the people who know the game best have stopped recommending it, and the store page score is flattering it.
Sentiment per credibility band. Reviews are banded by hours played at the time of writing:
| Band | Hours | What it means |
|---|---|---|
drive_by | under 2 | Inside Steam's refund window. Mostly refunds in progress. |
casual | 2–10 | Formed a first impression. |
engaged | 10–50 | Played it properly. |
invested | 50–200 | Knows the game. |
veteran | 200+ | Knows it better than most of the dev team. |
veteranPositivePercent dropping below driveByPositivePercent is the single
strongest churn signal Steam exposes, and it is invisible in a flat review list.
The distortion flags. refunded, receivedForFree,
writtenDuringEarlyAccess, onSteamDeck. Free copies skew positive. Early
access reviews often describe a build that no longer exists. Deck-specific
complaints hide inside general sentiment. All four are on every row, plus
per-app shares in the analysis.
Who uses this
- Game publishers and studios — watch veteran sentiment after a patch, not the review-bomb noise.
- Competitive analysis — pull five rival titles and compare weighted sentiment side by side.
- Investors and M&A — a raw score is easy to inflate; a weighted score with refund share attached is not.
- Storefronts and curators — filter out reviews below 2 hours before you quote a number.
Input
{"appIds": ["730", "https://store.steampowered.com/app/570/Dota_2/"],"maxReviewsPerApp": 1000,"filter": "recent","language": "english","minPlaytimeHours": 2,"excludeFreeCopies": true}
Paste bare App IDs or full store URLs — both work. The App ID is the number in
the store URL: 730 in store.steampowered.com/app/730/.
| Field | Default | Notes |
|---|---|---|
appIds | ["730"] | Required. IDs or store URLs. |
maxReviewsPerApp | 500 | 500 is enough to see a trend, 2000 for a definitive read. |
filter | recent | recent | updated | all (Steam's helpfulness ranking). |
language | all | Steam language code, e.g. english, schinese. |
reviewType | all | positive or negative only. |
purchaseType | all | Steam purchases vs keys and gifts. |
minPlaytimeHours | — | Set 2 to drop everything inside the refund window. |
excludeFreeCopies | false | Drop reviews from people who did not pay. |
includeAnalysis | true | The per-app summary row. |
includeReviews | true | Turn off for analysis only. |
Output
Three row types in one dataset, with tab views for each:
analysis — one row per app.
{"type": "analysis","appName": "Counter-Strike 2","reviewsAnalysed": 500,"rawPositivePercent": 71.2,"weightedPositivePercent": 63.8,"weightingEffect": -7.4,"veteranPositivePercent": 58.1,"driveByPositivePercent": 79.4,"medianPlaytimeAtReviewHours": 41.6,"refundedShare": 1.2,"freeCopyShare": 0.4,"lifetimeTotalReviews": 1490660,"lifetimeScoreDesc": "Very Positive"}
review — one row per review.
{"type": "review","votedUp": false,"playtimeAtReviewHours": 512.3,"playtimeTotalHours": 698.1,"credibility": "veteran","weight": 0.98,"refunded": false,"receivedForFree": false,"writtenDuringEarlyAccess": false,"onSteamDeck": true,"helpfulVotes": 120,"review": "...","reviewUrl": "https://steamcommunity.com/profiles/.../recommended/730/"}
app — store metadata: developers, publishers, price, discount, genres,
release date, Metacritic. Free, one per app.
Reliability
- Public, official, unauthenticated Steam endpoints. No login, no session cookie, no scraping of logged-in pages.
- One bad App ID never fails the run — it is recorded in
RUN_SUMMARYand the remaining apps continue. - An app with reviews but no store page (delisted, region-locked) still returns its reviews.
- 429 and 5xx are retried with exponential backoff; requests are paced.
Pricing
Pay per result. The per-app analysis row and every review row are charged;
the app metadata row is free.
Limits
- Steam has no star rating — reviews are Recommended / Not Recommended only.
playtime_at_reviewis absent on a small number of older reviews. Those getcredibility: nulland a low default weight, and they are excluded when you setminPlaytimeHours.- The analysis is computed over the reviews collected, before
minPlaytimeHoursandexcludeFreeCopiesare applied to the review rows — otherwise the analysis would only ever report whatever the filter selected. - Steam's lifetime totals in the analysis cover all reviews ever written, not your sample. Both are on the row so you can see the difference.