Google Play Apps Scraper
Pricing
from $1.40 / 1,000 results
Google Play Apps Scraper
Apps, keyword search and developer catalogues from the Google Play Store. Publishes both of the rating counts Google ships — they disagree by up to 6% — and refuses an unknown storefront country rather than letting Google price the app from your exit IP.
Pricing
from $1.40 / 1,000 results
Rating
0.0
(0)
Developer
Ibnu Adzim
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Apps, keyword search and developer catalogues from the Google Play Store. HTTP-only, no API key, no login, no browser.
Modes
| Mode | What you get |
|---|---|
apps | The full app document for package ids you name — ratings, install counts, price, developer, category, content rating, release date. |
search | Play Store keyword search. 30 apps per page; add fetchAppDetails to enrich each one. |
developer | Every app published by one developer. |
Four upstream quirks it corrects
1. The page ships two rating counts, and they disagree — on every app
An app page carries a JSON-LD aggregateRating and a ds:9 data block.
They are not the same numbers. Measured in the same response, the same minute:
| App | JSON-LD count | data layer total | gap |
|---|---|---|---|
com.whatsapp | 242,062,178 | 237,517,908 | 4,544,270 (1.9%) |
com.spotify.music | 36,189,697 | 34,027,397 | 2,162,300 (6.0%) |
com.duolingo | 49,046,761 | 46,446,301 | 2,600,460 (5.3%) |
com.mojang.minecraftpe | 5,804,850 | 4,566,585 | 1,238,265 (21.3%) |
That last row came from the first cloud run, after the docs had already claimed the gap tops out around 6% based on the three apps in reconnaissance. It does not. Treat the discrepancy as unbounded — there is no ratio you can correct one figure by to obtain the other.
The averages disagree too — 4.617702 vs 4.6164336, 4.343110 vs 4.3147283, 4.731406 vs 4.728731. And the data layer's own five-star histogram does not sum to its own stated total: WhatsApp's buckets add to 237,517,829 against a stated 237,517,908.
Nothing in the payload says which figure answers "how many people rated
this". So nothing here reconciles them. Both are published under names that
state their source — ratingCountFromJsonLd, ratingCountFromDataLayer,
ratingAverageFromJsonLd, ratingAverageFromDataLayer — the histogram ships
with its own arithmetic as ratingHistogramSum, and every row carries
ratingCountsDisagree and ratingCountGap so the discrepancy is visible on
the record rather than discovered later in aggregate.
2. country changes the price, and an unknown one is priced from your exit IP
Same app, com.mojang.minecraftpe, same minute:
country=US -> 6.99 USD country=GB -> 6.99 GBP country=ID -> 19000 IDRcountry=ZZ -> 19000 IDR <- bogus, priced from the EXIT IP
Google Play does not reject an unrecognised country. It silently falls back
to the storefront of whatever IP the request came from — so the same input
would produce different prices depending on where the run executed. This actor
validates country against a known list and refuses an unknown one before
spending a request. Every row records countryQueried so the storefront the
figures came from is never in doubt.
3. …but country is inert on search
q=vpn with gl=US, gl=GB and gl=ID returned the identical 30 packages
in identical order. The parameter that decides pricing does nothing to search
results. Stated on every summary as
countryAffectsPriceNotSearchResults: true, so nobody builds a
region-comparison on a dimension that does not move.
4. Install counts are rounded down, hard
Installs live only in the data layer, as a display string and an exact
figure: WhatsApp shows "10,000,000,000+" against an actual
12,257,877,869. Both are published (installsDisplayed, installsExact) —
the rounded one understates by over two billion.
Output
One SEARCH_SUMMARY per run, one APP per app, one ERROR per failure.
APP rows carry packageId, appUrl, appName, description, category,
operatingSystem, contentRating, iconUrl, developerName,
developerUrl, both rating pairs, ratingHistogram, ratingHistogramSum,
ratingCountsDisagree, ratingCountGap, price, priceCurrency, isFree,
availability, installsDisplayed, installsExact, releasedOn,
countryQueried, languageQueried and resultRank.
In search and developer mode without fetchAppDetails, rows are the
ordered package list only — one request total instead of one per app.
Limits
- No top-charts mode.
/store/apps/collection/*returns 937 KB of HTML whose content block is 59 bytes and which contains zero package ids — the chart is rendered client-side. Declared unavailable rather than shipped as a mode that silently returns nothing. - A search page yields 30 apps and exposes no next-page control in the served HTML.
- Prices and availability are the storefront's, not a user's — no account, no device filter, no regional carrier pricing.
- There is no WAF on this host: 8 TLS profiles × 4 surfaces returned 32 clean responses with a full data layer. A proxy is offered for data-quality reasons (see quirk 2), not for access.