Google Play Store Scraper (Apps, Charts, Similar, Reviews) avatar

Google Play Store Scraper (Apps, Charts, Similar, Reviews)

Pricing

from $1.00 / 1,000 app records

Go to Apify Store
Google Play Store Scraper (Apps, Charts, Similar, Reviews)

Google Play Store Scraper (Apps, Charts, Similar, Reviews)

Google Play app details, search results, developer catalogs, similar apps and top charts as clean JSON for any country: rating, installs, price, in-app purchases, content rating, version, last update, developer contact, screenshots and optional recent reviews. One record per app.

Pricing

from $1.00 / 1,000 app records

Rating

0.0

(0)

Developer

Matthew Curtis

Matthew Curtis

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Categories

Share

Turn any Google Play query into clean JSON: app details, search results, developer catalogs, similar-apps clusters and top charts, for one or many countries in a single run, with optional recent reviews embedded in each app record. Built for reliability and speed — one app lookup returns in about a second, a 120-app run finishes in under 30 seconds — and priced per app record so a single lookup costs well under a cent.

Typical uses: ASO and competitor tracking, market research (installs, ratings, price, IAP range per country), lead lists of app publishers (developer website and support email are public on every listing), app-store monitoring in agents and automations, and keeping a product database in sync with Play Store metadata.

What you get

One dataset item per app. App-id queries always return the full record; search and developer queries return the full record when Fetch full details is on (default) or a lighter listing card when it is off.

FieldMeaning
idAndroid package name (com.spotify.music) — the stable key
urlPlay Store URL for the requested locale
title, summaryListing title and short description
descriptionSnippet, descriptionLengthFirst 300 characters of the long description plus its full length (the full text is not reproduced — follow url for it)
developer{ name, id, url, website, email, legalName, address } as shown publicly on the listing
price, currency, priceText, freePrice in the store front's currency (0 = free)
offersInAppPurchases, inAppPurchaseRangeIAP flag and the displayed range ("$4.99 - $203.88 per item")
score, scoreText, ratingsCount, reviewsCount, histogramAverage rating (null for apps with too few ratings), counts and 1–5 star histogram
installs, minInstalls, maxInstallsDisplayed install bucket and Google's numeric bounds
genre, genreId, categories[]Category name and id (MUSIC_AND_AUDIO)
contentRating, contentRatingDescriptionAge rating for the locale (Teen, USK ab 0 Jahren, …)
adSupported, available, preregister, playPassFlags
released, updatedAt, version, androidVersionRelease date as displayed, last update as ISO 8601, current version (null when it "varies with device")
recentChangesSnippetFirst 300 characters of "What's new"
privacyPolicyUrl, icon, headerImage, images[], videoLinks to the listing's media (not downloaded)
reviews[]Only when Recent reviews per app > 0: { id, author, score, text (≤300 chars), textTruncated, date, thumbsUp, appVersion, replyText, replyDate, url }, newest first
locale, kind, source, scrapedAtlocale = {language, country}; kind = detail or listing; source = {query, type, rank} says which query produced the record and its position in that result list

Listing cards (kind: "listing") carry id, url, title, summary, developer {name, id}, score, scoreText, price, currency, free, icon plus locale, source, scrapedAt.

Sample record

{
"id": "com.spotify.music",
"url": "https://play.google.com/store/apps/details?id=com.spotify.music&hl=en&gl=us",
"title": "Spotify: Music and Podcasts",
"summary": "Listen to songs, play podcasts, create playlists and discover music you'll love",
"descriptionSnippet": "With the Spotify music and podcast app, you can play millions of songs, albums and original podcasts for free. We have e…",
"descriptionLength": 3868,
"developer": {
"name": "Spotify AB",
"id": "Spotify AB",
"url": "https://play.google.com/store/apps/developer?id=Spotify%20AB&hl=en&gl=us",
"website": "https://www.spotify.com",
"email": "support@spotify.com",
"legalName": "Spotify AB",
"address": "Regeringsgatan 19, 111 53 Stockholm, Sweden"
},
"price": 0, "currency": "USD", "priceText": "Free", "free": true,
"offersInAppPurchases": true, "inAppPurchaseRange": "$4.99 - $203.88 per item",
"score": 4.3491316, "scoreText": "4.3", "ratingsCount": 36534575, "reviewsCount": 1857195,
"histogram": { "1": 3715958, "2": 1065335, "3": 1308283, "4": 3102776, "5": 27342207 },
"installs": "1,000,000,000+", "minInstalls": 1000000000, "maxInstalls": 3172798659,
"genre": "Music & Audio", "genreId": "MUSIC_AND_AUDIO",
"categories": [{ "name": "Music & Audio", "id": "MUSIC_AND_AUDIO" }],
"contentRating": "Teen", "contentRatingDescription": null,
"adSupported": true, "available": true, "preregister": false, "playPass": false,
"released": "May 27, 2014", "updatedAt": "2026-10-23T12:37:22.000Z",
"version": null, "androidVersion": null,
"recentChangesSnippet": "We’re always making changes and improvements to Spotify. To make sure you don’t miss a thing, just keep your Updates turned on.",
"privacyPolicyUrl": "https://www.spotify.com/legal/privacy-policy/",
"icon": "https://play-lh.googleusercontent.com/IzQgYCcnCFCD08GR-3bdtcT8xzOvrNkC84avGT5CwTX2VIqmTmKKJcP_Cd4JoBOdmCMlTndlOzV6hrthg2fOWA",
"headerImage": "https://play-lh.googleusercontent.com/WdedaGD6EAXZgy88wZM97aIcenQ5Cqzu_IUWBMMalkZmVe2lhv_3YqIUh-6pFqLv27kZ44cQX3qxyZTXHH-S91Q",
"images": ["https://play-lh.googleusercontent.com/c1jnjL-9CIFlwlTMX3xNyeo8aEH39sNuC5zpTHhfW8keGxQE3TBMRX9Rm3VqM3E03Cyl9AqtnxuKvxJpcW0WCA", "… 39 more"],
"video": null,
"reviews": [
{ "id": "c8a50b3d-232e-45ae-b30a-99bc96c67830", "author": "Allison H.", "score": 1, "text": "No easy way to delete your account …", "textTruncated": false, "date": "2026-10-06T18:09:25.911Z", "thumbsUp": 0, "appVersion": null, "replyText": null, "replyDate": null, "url": "https://play.google.com/store/apps/details?id=com.spotify.music&reviewId=c8a50b3d-232e-45ae-b30a-99bc96c67830" }
],
"locale": { "language": "en", "country": "us" },
"kind": "detail",
"source": { "query": "com.spotify.music", "type": "app", "rank": null },
"scrapedAt": "2026-10-24T23:39:19.707Z"
}

Input

FieldTypeDefaultWhat it does
queriesstring[]["meditation"]What to look up. Each entry is auto-detected: a package name (com.spotify.music) → app details; a search term (meditation) → search results; dev:Spotify AB, a numeric developer id (5700313618786177705) or a developer URL → that publisher's catalog; similar:com.spotify.music → Google's "Similar apps" cluster for that app; chart:TOP_FREE, chart:TOP_PAID:GAME, chart:GROSSING:FINANCE → top charts (collections TOP_FREE, TOP_PAID, GROSSING; any Play category id such as GAME, FINANCE, GAME_PUZZLE; default all apps); any play.google.com app / search / developer / cluster URL also works.
localesstring[]["en-US"]One or more store fronts as language-COUNTRY. Every query runs once per store front and each (app, country) pair is its own record, so one run compares prices, currency, availability, content ratings and rankings across countries. de-DE, pt-BR, ja-JP, en-IN, …
maxItemsinteger50Upper bound on app records for the whole run (1–5000). Direct app ids take one slot each; the rest is split evenly across listing queries × store fronts, so maxItems: 50 with five keywords returns the top 10 of each. Each record is one charged dataset item.
fetchDetailsbooleantrueOpen every app found by a search or developer query for the full record. Turn off for a cheap shortlist (one request per query, no per-app requests).
reviewsPerAppinteger0Embed up to this many newest reviews (0–200) in each app record. Reviews are part of the record and are not charged separately.
knownIdsstring[][]Incremental mode — app ids you already have are skipped before any request is made (see Monitoring below).
proxyConfigurationobjectApify datacenter proxyGoogle Play serves datacenter IPs at polite rates; switch to residential only if SUMMARY.blocked is ever non-zero.

Examples

One app, full record (the agent / MCP call):

{ "queries": ["com.spotify.music"], "locale": "en-US", "maxItems": 1 }

Top results for a keyword in Germany with the 20 newest reviews each:

{ "queries": ["haushaltsbuch"], "locale": "de-DE", "maxItems": 20, "reviewsPerApp": 20 }

A publisher's whole catalog as a cheap shortlist (no detail requests):

{ "queries": ["dev:Microsoft Corporation", "5700313618786177705"], "maxItems": 500, "fetchDetails": false }

Competitor set and charts for a category, compared across three countries:

{ "queries": ["similar:com.duolingo", "chart:TOP_FREE:EDUCATION", "chart:GROSSING:EDUCATION"], "locales": ["en-US", "pt-BR", "ja-JP"], "maxItems": 300 }

Pricing

Pay per event, no subscription:

EventPrice
Actor start$0.005 per run (per GB of memory, minimum one — the Actor runs in 256 MB)
App record$0.001 per dataset item

A single app lookup therefore costs $0.006; 1,000 full app records with reviews cost about $1.01 plus your platform compute (a few seconds per hundred apps). Embedded reviews are free: 200 reviews for an app come inside one $0.001 record. There is no extra charge for different locales, for developer catalogs or for listing cards.

Monitoring / incremental recipe

Schedule the Actor with the queries you care about and pass the app ids you already hold in knownIds. Only apps that are new in that search or catalog since last time are fetched and charged, so a daily "new apps for keyword X / new releases by publisher Y" monitor costs the Actor start plus a handful of records. To track metadata changes of known apps (new version, rating movement, price change), schedule a run with those package names as queries and diff the version, updatedAt, score, ratingsCount and price fields; each app is one record.

The run also writes a SUMMARY record to the key-value store with counts (pushed, duplicatesSkipped, knownSkipped, notFound, blocked, rateLimited), the time to the first record, p95 latency, the adaptive timeout, peak concurrency and any inferred rate limit — handy for alerting.

Speed and reliability

Measured on the live site on 25 Oct 2026 from a datacenter IP (see tests.md): a single app lookup pushed its record 1.1 s after start; a 10-app search with 20 reviews each took 5.6 s (≈107 records/min including 200 reviews); an 86-record developer + similar-apps shortlist took 2.1 s (5 requests); a 225-record run across a search, a developer, a similar-apps cluster and two charts took 44 s at up to 8 concurrent requests (≈310 records/min), 233 requests, 0 failures.

Under the hood: plain HTTP only (no browser — the data is server-rendered), Google's own continuation endpoint for pagination, adaptive concurrency that starts at 2 and grows only while the error rate stays under 2% (and halves on throttling), a per-host minimum delay, timeouts derived from the measured latency distribution, transient errors retried up to three times, challenge pages detected and counted instead of retried, and every record deduplicated by package name before it is pushed. If a page is not found (removed app, wrong id) it is logged and skipped, never retried.

Limitations

  • Google Play returns at most about 25–30 results for a search term without a signed-in session; that is what every scraper gets. For more coverage use several related terms, or a developer query (catalogs paginate to a few hundred apps).
  • description and recentChanges are returned as 300-character snippets with the full length; reviews are snippets too (textTruncated tells you when). Media is linked, not downloaded.
  • score / ratingsCount are null for apps that do not yet show a rating. version and androidVersion are null when Google shows "Varies with device". priceText for free apps is "Free" in every locale.
  • The data-safety section and app permissions are not collected (Google disallows that path for crawlers).
  • Top charts return up to 200 apps per collection/category (Google's cap); similar: clusters return the first 50 Google shows, with continuation when available. When a listing query has fewer apps than its share of maxItems, the unused share is not redistributed to other queries, so a run can finish below maxItems.
  • Pre-registration and unavailable apps are returned with available: false / preregister: true and whatever fields Google shows.
  • Country availability matters: an app that is not published in the selected locale country returns a not-found page and is skipped.

Get alerted when records change

Pair this Actor with Dataset Diff & Alert Monitor to receive only the new, changed or removed records in Slack, Discord, Telegram or a webhook. Schedule the monitor, not this Actor: it runs this Actor for you, compares runs by id, and a run that finds nothing costs only the comparison. This is the competitor watch from the recipe above without writing the diff yourself: a new version, a rating move or a price change on any tracked app becomes one message.

{
"sourceActorId": "mdcurt/google-play-app-scraper",
"sourceInput": {
"queries": [
"com.duolingo",
"com.babbel.mobile.android.en"
],
"locale": "en-US",
"maxItems": 2
},
"keyFields": [
"id"
],
"watchFields": [
"version",
"score",
"ratingsCount",
"price",
"updatedAt"
],
"notifyOn": [
"changed"
],
"labelField": "title",
"urlField": "url",
"slackWebhookUrl": "https://hooks.slack.com/services/…"
}

Changelog

  • 1.1.0 (2026-10-25) — Similar-apps clusters (similar:), top charts (chart:COLLECTION:CATEGORY), cluster URLs, multi-country locales list, fair per-query split of maxItems, per-locale record keys.
  • 1.0.0 (2026-10-24) — Initial release: app details, search, developer catalogs with continuation paging, embedded recent reviews, locale support, incremental knownIds, adaptive concurrency and timeouts, SUMMARY record.