Guides · Google Play Reviews Scraper · Published July 15, 2026

Export Google Play reviews to CSV with Python and pandas

Pull any app's Google Play reviews into a pandas DataFrame and out to CSV: package name in, one row per review with rating, text, and developer reply. Sorting options, cost math ($0.08 per 1,000), and the failure rows to filter first.

By slvDev · Updated and technically verified July 15, 2026


The short answer:Google Play has no public API for reading another app's reviews — the official Reviews API is Play-Console-gated to apps you own. For any public app, the Google Play Reviews Scraper takes a package name (or store URL), returns one JSON record per review — rating, text, author, developer reply, app version, date — and pandas turns that into a CSV in three lines. $0.08 per 1,000 reviews; apps with no reviews return a free typed row. Full script below.

Setup

pip install apify-client pandas

The token comes from Apify Console → Settings → API tokens (free tier works). No Google account, no Play Console access.

Package name → DataFrame → CSV

import os
import pandas as pd
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("apihq/google-play-reviews-scraper").call(
    run_input={
        "appIds": ["com.spotify.music"],   # or the full Play Store URL
        "maxReviews": 2000,
        "sort": "newest",                  # newest | helpful | rating
        "country": "us",
        "language": "en",
    }
)

items = list(client.dataset(run["defaultDatasetId"]).iterate_items())

reviews = [r for r in items if r["success"]]        # billed: $0.00008 each
misses  = [r for r in items if not r["success"]]    # free, typed

for m in misses:
    print(m.get("app_id"), "->", m["code"])          # e.g. NO_REVIEWS

df = pd.DataFrame(reviews)
df.to_csv("play_reviews.csv", index=False)
print(f"{len(df)} reviews -> play_reviews.csv")

Filtering on success first matters: a wrong package name or an app with no reviews in the requested locale comes back as a typed success: false row (NO_REVIEWS, VALIDATION_FAILED — the registry has all of them), not as an exception — and not on your bill. Batch several apps in one run by adding more package names to appIds; one bad app never blocks the others.

Two lines of analysis to start from

# rating distribution (the star rating lives in "score")
print(df["score"].value_counts().sort_index())

# the newest 1-star complaints, for reading
one_star = df[df["score"] == 1][["posted_at", "text"]].head(20)

From here the usual moves are sentiment scoring on text, grouping by app_version to spot a release that tanked ratings, and checking which complaints have a reply_text and which are being ignored.

Cost math

  • 2,000 reviews, as in the script: $0.16.
  • 10,000 reviews across five competitor apps: $0.80.
  • A daily "newest 100" snapshot: about $0.24 per app per month — there's an importable n8n template for exactly that.

Honest limits

  • Reviews are localized. Google Play serves one country/language per run (country and language, defaulting to us/en). Covering another market means running the app again with different values.
  • Public data only: what a signed-out visitor sees on the store listing. Beta-channel feedback and Play Console replies data stay in the Console.
  • If you own the app, the official Play Developer Reply-to-Reviews API is the supported route — it just doesn't work for anyone else's app, which is what this actor is for.

Deploying this?

Run one input on the Google Play Reviews Scraper. It comes back as either a billed review row or an unbilled, typed failure row — the contract this guide builds on.

A one-item first run costs under a cent, on your existing Apify account.