Modern, typed Google Play Store scraper client with Pydantic models.
Project description
play-store-scraper-ng
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".
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)AppDetails: extendsAppOverviewwith 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 parsedParsingError: Unexpected response structureQuotaExceeded: Rate-limited or temporarily blocked by GoogleGooglePlayError: 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_secondto avoid temporary blocking - Proxies: pass a
requests-style proxies dict (e.g.,{ "http": "http://host:port", "https": "http://host:port" }) - SSL: set
verify_ssl=Falseonly for troubleshooting
Best practices and Notes
- Use conservative
throttle_requests_per_secondand 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 detailsdemo/sync/demo_search.py— search appsdemo/sync/demo_list.py— list collections and categoriesdemo/sync/demo_reviews.py— fetch reviews with paginationdemo/sync/demo_suggest.py— query suggestions
Async demos:
demo/async/demo_app.py— fetch app detailsdemo/async/demo_search.py— search appsdemo/async/demo_list.py— list collections and categoriesdemo/async/demo_reviews.py— fetch reviews with paginationdemo/async/demo_suggest.py— query suggestions
Run with:
python -m demo.sync.demo_app
python -m demo.async.demo_app
Links
- PyPI: https://pypi.org/project/play-store-scraper-ng/
- Source: https://github.com/RankoR/google-play-scraper
- Issues: https://github.com/RankoR/google-play-scraper/issues
Contributing
PRs and issues are welcome! Please run tests locally before submitting changes.
License
MIT License. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file play_store_scraper_ng-0.1.5.tar.gz.
File metadata
- Download URL: play_store_scraper_ng-0.1.5.tar.gz
- Upload date:
- Size: 19.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb51bc724324527b95679571c98e927d28982cd423debcc0872669278184c2ec
|
|
| MD5 |
6de4d94ef86d06762989521e7e0759a7
|
|
| BLAKE2b-256 |
c1a2a1817510b4f05937e1b82a401aceb2c4ab7a6f64d6cf3ffff1c53b6d5e1b
|
Provenance
The following attestation bundles were made for play_store_scraper_ng-0.1.5.tar.gz:
Publisher:
release.yml on RankoR/google-play-scraper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
play_store_scraper_ng-0.1.5.tar.gz -
Subject digest:
cb51bc724324527b95679571c98e927d28982cd423debcc0872669278184c2ec - Sigstore transparency entry: 798246659
- Sigstore integration time:
-
Permalink:
RankoR/google-play-scraper@467f06ef10a6b469d978893fb09988eaf79d0fe5 -
Branch / Tag:
refs/tags/releases/0.1.5 - Owner: https://github.com/RankoR
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@467f06ef10a6b469d978893fb09988eaf79d0fe5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file play_store_scraper_ng-0.1.5-py3-none-any.whl.
File metadata
- Download URL: play_store_scraper_ng-0.1.5-py3-none-any.whl
- Upload date:
- Size: 18.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
201e4f9a1a1aedd3bcc5eb19bf148099b168b1fc73b2943be55d042303ac061c
|
|
| MD5 |
175ad8e22878ce6323219704a94231fa
|
|
| BLAKE2b-256 |
0f1592f41756fb02d7a414a1207f57b1d2e0bfb2a4b860be6e5dd537a71ef0f8
|
Provenance
The following attestation bundles were made for play_store_scraper_ng-0.1.5-py3-none-any.whl:
Publisher:
release.yml on RankoR/google-play-scraper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
play_store_scraper_ng-0.1.5-py3-none-any.whl -
Subject digest:
201e4f9a1a1aedd3bcc5eb19bf148099b168b1fc73b2943be55d042303ac061c - Sigstore transparency entry: 798246661
- Sigstore integration time:
-
Permalink:
RankoR/google-play-scraper@467f06ef10a6b469d978893fb09988eaf79d0fe5 -
Branch / Tag:
refs/tags/releases/0.1.5 - Owner: https://github.com/RankoR
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@467f06ef10a6b469d978893fb09988eaf79d0fe5 -
Trigger Event:
push
-
Statement type: