Google Play Apps Scraper avatar

Google Play Apps Scraper

Pricing

from $1.40 / 1,000 results

Go to Apify Store
Google Play Apps Scraper

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

Ibnu Adzim

Maintained by Community

Actor 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

ModeWhat you get
appsThe full app document for package ids you name — ratings, install counts, price, developer, category, content rating, release date.
searchPlay Store keyword search. 30 apps per page; add fetchAppDetails to enrich each one.
developerEvery 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:

AppJSON-LD countdata layer totalgap
com.whatsapp242,062,178237,517,9084,544,270 (1.9%)
com.spotify.music36,189,69734,027,3972,162,300 (6.0%)
com.duolingo49,046,76146,446,3012,600,460 (5.3%)
com.mojang.minecraftpe5,804,8504,566,5851,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 IDR
country=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.

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.