Skip to main content

play-store-scraper-ng

Tests PyPI version

Modern, typed Google Play Store scraper client for Python. Fetch app details, search results, top lists, reviews, and search suggestions with a clean API and Pydantic models.

Based on and inspired by the original work at https://github.com/facundoolano/google-play-scraper, reworked with type hints, Pydantic models, and a simpler client API.

Features

  • Simple high-level client: GooglePlayClient
  • Typed data models for responses via Pydantic: AppDetails, AppOverview, Review
  • Search apps, fetch app details, list collections, reviews with pagination, and query suggestions
  • Locale and country support (e.g., hl=en, gl=us)
  • Optional throttling, proxy support, and SSL verification control
  • Python 3.11+

Installation

Install from PyPI:

pip install play-store-scraper-ng

Requires Python 3.11 or newer.

Quickstart

from google_play_scraper import GooglePlayClient

client = GooglePlayClient(country="us", lang="en")

# Fetch app details by ID
details = client.app("com.whatsapp")
print(details.title, details.score, details.installs)

# Search apps
results = client.search("todo list", num=10)
for app in results:
    print(app.title, app.score)

Async Usage

The client also supports async usage with httpx. Async methods are prefixed with 'a' (e.g., app -> aapp). All synchronous methods have an asynchronous equivalent.

import asyncio
from google_play_scraper import GooglePlayClient, Sort, Collection, Category

async def main():
    client = GooglePlayClient()

    # Async app details
    details = await client.aapp("com.whatsapp")
    print(f"App: {details.title}, Score: {details.score}")

    # Async search
    results = await client.asearch("photo editor", num=5)
    for app in results:
        print(f"Search result: {app.title}")

    # Async list
    top_free_games = await client.alist(
        collection=Collection.TOP_FREE,
        category=Category.GAME,
        num=10
    )
    for app in top_free_games:
        print(f"Top game: {app.title}")

    # Async reviews
    reviews, _ = await client.areviews("com.burbn.instagram", sort=Sort.NEWEST, num=5)
    for r in reviews:
        print(f"Review by {r.user_name}: {r.text[:50]}...")

    # Async suggestions
    suggestions = await client.asuggest("video")
    print(f"Suggestions for 'video': {suggestions}")


if __name__ == "__main__":
    asyncio.run(main())

Usage

Client initialization

from google_play_scraper import GooglePlayClient

client = GooglePlayClient(
    country="us",                 # default country code for requests
    lang="en",                    # default language for responses
    proxies={"https": "http://host:port"},  # optional proxies for requests.Session
    throttle_requests_per_second=2,            # optional rate limit
    verify_ssl=True               # set to False to skip SSL verification (not recommended)
)

Parameters may be overridden per-call where supported (see below).

Get app details

from google_play_scraper import GooglePlayClient

client = GooglePlayClient()
app = client.app("com.spotify.music", lang="en", country="us")

print(app.title)
print(app.score, app.score_text)
print(app.price, app.currency)
print(app.developer, app.developer_email)
print(app.installs, app.min_installs, app.max_installs)
print(app.updated)
print(app.screenshots[:3])

Returns an AppDetails model (extends AppOverview).

Search

from google_play_scraper import GooglePlayClient

client = GooglePlayClient()
apps = client.search("timer", num=20, price="all", lang="en", country="us")
for a in apps:
    # a is AppOverview
    print(a.app_id, a.title, a.score)

price can be one of: "all" (default), "free", "paid".

num caps the results. Google Play serves search results as a single page and no longer offers a "next page" for them, so a query yields roughly 20-30 apps no matter how large num is.

List collections

from google_play_scraper import GooglePlayClient, Collection, Category, Age

client = GooglePlayClient()

top_free_tools = client.list(
    collection=Collection.TOP_FREE,
    category=Category.TOOLS,
    num=50,
    lang="en",
    country="us",
)

for app in top_free_tools:
    print(app.title, app.score)

See google_play_scraper.constants for available Category, Collection, and Age values.

Reviews with pagination

from google_play_scraper import GooglePlayClient, Sort

client = GooglePlayClient()

reviews, next_token = client.reviews(
    app_id="com.whatsapp",
    sort=Sort.NEWEST,     # or Sort.RATING / Sort.HELPFULNESS
    num=100,              # number of reviews to fetch (up to a server-side limit)
    lang="en",
    country="us",
)

client.reviews returns a tuple of (reviews: list[Review], next_token: str | None). To request the next page, pass the token to the next call:

from google_play_scraper import GooglePlayClient

client = GooglePlayClient()
reviews, next_token = client.reviews("com.whatsapp", num=100)
if next_token:
    more_reviews, next_token = client.reviews("com.whatsapp", num=100, pagination_token=next_token)

Search suggestions

from google_play_scraper import GooglePlayClient

client = GooglePlayClient()
suggestions = client.suggest("photo ed")
print(suggestions)

Data models

All return types are validated Pydantic models that are easy to consume and serialize.

  • AppOverview: minimal data used in lists/search (e.g., title, app_id, score, icon, developer). developer_id is only populated by app() — Play omits it from list and search payloads
  • AppDetails: extends AppOverview with rich metadata (e.g., description, installs, histogram, price, genre, screenshots, updated)
  • Review: normalized review entry (score, text, user_name, thumbs_up, dates, developer reply info)

See google_play_scraper/models.py for full fields.

Constants

Import enums to control listing and sorting:

from google_play_scraper import Category, Collection, Sort, Age

Error handling

Common exceptions:

  • AppNotFound: App ID does not exist or could not be parsed
  • ParsingError: Unexpected response structure
  • QuotaExceeded: Rate-limited or temporarily blocked by Google
  • GooglePlayError: Base class for library errors

Handle errors explicitly:

from google_play_scraper import GooglePlayClient
from google_play_scraper import AppNotFound, GooglePlayError

client = GooglePlayClient()
try:
    app = client.app("com.nonexistent.app")
except AppNotFound:
    print("App not found")
except GooglePlayError as e:
    print("General error:", e)

Configuration, proxies, and rate limiting

  • Locale/country: set defaults via GooglePlayClient(country=..., lang=...) and override per call
  • Rate limiting: throttle_requests_per_second to avoid temporary blocking
  • Proxies: pass a requests-style proxies dict (e.g., { "http": "http://host:port", "https": "http://host:port" })
  • SSL: set verify_ssl=False only for troubleshooting

Best practices and Notes

  • Use conservative throttle_requests_per_second and caching when scraping at scale
  • Respect Google Play Terms of Service and robots.txt. This library is for educational and research purposes; use responsibly
  • API responses and page structures can change without notice; pin versions and add monitoring

Examples and demos

See the demo/ directory for runnable examples.

Sync demos:

  • demo/sync/demo_app.py — fetch app details
  • demo/sync/demo_search.py — search apps
  • demo/sync/demo_list.py — list collections and categories
  • demo/sync/demo_reviews.py — fetch reviews with pagination
  • demo/sync/demo_suggest.py — query suggestions

Async demos:

  • demo/async/demo_app.py — fetch app details
  • demo/async/demo_search.py — search apps
  • demo/async/demo_list.py — list collections and categories
  • demo/async/demo_reviews.py — fetch reviews with pagination
  • demo/async/demo_suggest.py — query suggestions

Run with:

python -m demo.sync.demo_app
python -m demo.async.demo_app

Links

Contributing

PRs and issues are welcome! Please run tests locally before submitting changes.

License

MIT License. See LICENSE.

Release files for play-store-scraper-ng 0.1.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for play-store-scraper-ng 0.1.8
File Size Uploaded
play_store_scraper_ng-0.1.8.tar.gz 20.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for play-store-scraper-ng 0.1.8
File Interpreter ABI Platform
play_store_scraper_ng-0.1.8-py3-none-any.whl Python 3 none any Details

Total release size: 40.1 kB

Release files / play_store_scraper_ng-0.1.8.tar.gz

Download URL play_store_scraper_ng-0.1.8.tar.gz
Size 20.6 kB
Tags Source
SHA-256 checksum
How to use checksums
72da642c887bca493c4e0e85815bc78feb08a7f40db5e608756cdf6cfbec9f61
BLAKE2b-256 checksum
How to use checksums
694a16d4316f516e7cc4634085ab7faa46175cdedc2fae807ea84ce98e1f2cf3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 8, 2026.

Transparency log

Release files / play_store_scraper_ng-0.1.8-py3-none-any.whl

Download URL play_store_scraper_ng-0.1.8-py3-none-any.whl
Size 19.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b1397e2059833689c2ea46b2ef29468b982f8200b40c749eb8654fdf5ac7b5e0
BLAKE2b-256 checksum
How to use checksums
95df1663d5fa33c4d080644de0e996dcb7fe3463e5dfc0f0a504591696732878
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.8 This release

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page