Steam Reviews Scraper avatar

Steam Reviews Scraper

Pricing

from $0.70 / 1,000 reviews

Go to Apify Store
Steam Reviews Scraper

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

Datalayer

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

19 days ago

Last modified

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:

AppRaw %Weighted %Shift
Healthy game84.085.1+1.1
Game in trouble78.051.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:

BandHoursWhat it means
drive_byunder 2Inside Steam's refund window. Mostly refunds in progress.
casual2–10Formed a first impression.
engaged10–50Played it properly.
invested50–200Knows the game.
veteran200+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/.

FieldDefaultNotes
appIds["730"]Required. IDs or store URLs.
maxReviewsPerApp500500 is enough to see a trend, 2000 for a definitive read.
filterrecentrecent | updated | all (Steam's helpfulness ranking).
languageallSteam language code, e.g. english, schinese.
reviewTypeallpositive or negative only.
purchaseTypeallSteam purchases vs keys and gifts.
minPlaytimeHoursSet 2 to drop everything inside the refund window.
excludeFreeCopiesfalseDrop reviews from people who did not pay.
includeAnalysistrueThe per-app summary row.
includeReviewstrueTurn 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_SUMMARY and 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_review is absent on a small number of older reviews. Those get credibility: null and a low default weight, and they are excluded when you set minPlaytimeHours.
  • The analysis is computed over the reviews collected, before minPlaytimeHours and excludeFreeCopies are 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.