Paste any Google Play app and pick a country. Web Unlocker returns the exact rating and installs behind "4.7" and "500M+", version, price and 20 reviews with the developer's replies. $0.98 per 1,000 apps.
1,000 free requests · Pay only on success · 195+ countries · Claude ready
Google Play pages take 3 to 10 seconds. It is still working, no need to click again.
Ready for your own apps? Get an API key or book a demo.
Tell us a little about your team and get:
Google Play rounds what it shows: "4.7", "500M+". The page underneath holds the exact numbers, and one request returns them with 20 reviews. No Google account needed.
One request brings an app's whole page: rating, installs, version, price and 20 reviews. Web Unlocker bills it as one page. Apify and Bright Data bill the app and each of its reviews as a row, and SerpApi bills each search.
One app with 20 reviews is 21 rows on Apify.
Here it is one page.
A page that fails to load costs nothing. The same app from another country, its data safety page or a keyword search is one more page.
What 1,000 apps with 20 reviews each cost
1,000 app pages, details plus 20 reviews, at published prices
Gologin: $0.98 per 1,000 pages on the Growth plan. Apify: 1,000 app rows and 20,000 review rows, at $0.0007 and $0.00011 a row on one actor and $0.30 per 1,000 results on the other. SerpApi: 1,000 app searches on its $25 plan. Bright Data: 21,000 records at $1.50 per 1,000, pay as you go.
Ready to run it on your own apps? Get your API key and free requests.
Our Google Play scraping test, run twice an hour apart: 10 US apps three times each, 3 German apps, 2 keyword searches and 2 data safety pages, each asked up to 3 times like the demo above.
78 of 88 came back on the first try.
The other 10 on the second or third.
The open-source google-play-scraper library, Apify's Google Play actors and Bright Data's Google Play Scraper API: what each costs for the same 1,000 apps, and what it leaves to you.
| What it takes | google-play-scraper | |||
|---|---|---|---|---|
| You pay for | A page | Your own servers | Each row | Each record |
| 1,000 apps with 20 reviews | $0.98 | Free, from your IPs | $2.90 to $6.30 | $31.50 |
| Reviews per app | 20; more with Cloud Browser | Paged, 200 a call | Up to 100,000 | As many as you set |
| Search by keyword | Yes | Yes | Yes | No |
| Free to start | 1,000 requests | Free | $5 a month | 5,000 a month |
| The whole page in HTML | Yes | No | No | No |
| Same price on any other site | Yes | Google Play only | No | No |
Scraping more than Google Play? Web Unlocker returns any page the same way, at the same price.
Web Unlocker returns the 20 reviews an app page holds; the rest sit in Google's review feed. Cloud Browser, a separate Gologin product with its own plans, calls that feed from the app page: 2,000 of Duolingo's newest reviews in 4.5 seconds.
Ratings, installs, prices, search ranks and the top 20 reviews all come from Web Unlocker alone. Cloud Browser is for the full review history.
From the open app page, Cloud Browser asks Google's feed for 100 reviews at a time, newest first: 20 calls, 2,000 reviews, 4.5 seconds.
Cloud Browser is not part of Web Unlocker requests. Your Playwright or Puppeteer code, or Claude, drives it. Residential IPs included.
Run it from Playwright, Puppeteer or Claude. See Cloud Browser.
Google Play keeps an app's data as JSON inside its page, the same JSON the open-source google-play-scraper reads. Web Unlocker returns that page from the country you pick, and a few lines read the app, its 20 reviews or a keyword's search results out of it.
Fill in the form above. The key arrives by email within one business day.
An app page for its details and reviews, a search page for rankings, a data safety page for what the app collects.
Cut the app's data out of the page, and ask again at a fresh address when the page came without it.
pip install requestsGOLOGIN_SCRAPING_API_KEY=your_key python google_play_app.pyhttps://parsing.webunlocker.gologin.com/v1/scrapeimport json
import os
import re
import time
from datetime import datetime, timezone
import requests
app_id = "com.duolingo"
country = "us"
def scrape(url):
for attempt in range(3):
address = url if attempt == 0 else f"{url}&fresh={int(time.time())}"
response = requests.get(
"https://parsing.webunlocker.gologin.com/v1/scrape",
params={"url": address, "geo": country, "format": "json"},
headers={"apikey": os.environ["GOLOGIN_SCRAPING_API_KEY"]},
timeout=90,
)
page = response.json().get("data", {}).get("html", "") if response.ok else ""
if "key: 'ds:5'" in page:
return page
time.sleep(3)
raise RuntimeError("The page came back without the app data, try again later")
def blocks(page):
for key, data in re.findall(r"AF_initDataCallback\(\{key: '(ds:\d+)'.*?data:(.*?), sideChannel: \{\}\}\);</script>", page, re.S):
yield key, json.loads(data)
def at(node, *path):
for step in path:
if not isinstance(node, list) or step >= len(node):
return None
node = node[step]
return node
def day(stamp):
return datetime.fromtimestamp(stamp[0], timezone.utc).date().isoformat() if stamp else None
page = scrape(f"https://play.google.com/store/apps/details?id={app_id}&hl=en&gl={country.upper()}")
data = dict(blocks(page))
d = at(data["ds:5"], 1, 2)
reviews = next(
(value[0] for value in data.values() if isinstance(at(value, 0, 0, 0), str) and re.match(r"^[0-9a-f]{8}-", at(value, 0, 0, 0))),
[],
)
app = {
"id": app_id,
"title": at(d, 0, 0),
"developer": at(d, 68, 0),
"genre": at(d, 79, 0, 0, 0),
"rating": at(d, 51, 0, 1),
"ratings": at(d, 51, 2, 1),
"installs": at(d, 13, 0),
"installs_exact": at(d, 13, 2),
"price": (at(d, 57, 0, 0, 0, 0, 1, 0, 0) or 0) / 1e6,
"currency": at(d, 57, 0, 0, 0, 0, 1, 0, 1),
"version": at(d, 140, 0, 0, 0) or "Varies with device",
"updated": at(d, 145, 0, 0),
"reviews": [
{
"author": at(review, 1, 0),
"stars": at(review, 2),
"text": at(review, 4),
"date": day(at(review, 5)),
"helpful": at(review, 6),
"app_version": at(review, 10),
"reply": at(review, 7, 1),
}
for review in reviews
],
}
print(json.dumps(app, indent=2, ensure_ascii=False))
print(f"{app['title']}: {app['rating']:.2f} from {app['ratings']:,} ratings, {app['installs_exact']:,} installs, {len(app['reviews'])} reviews from one page")GOLOGIN_SCRAPING_API_KEY=your_key node google-play-apps.mjshttps://parsing.webunlocker.gologin.com/v1/scrapeimport { writeFileSync } from 'node:fs';
const apps = ['com.duolingo', 'com.babbel.mobile.android.en', 'com.memrise.android.memrisecompanion', 'com.busuu.android.enc', 'com.hellotalk'];
const country = 'us';
async function scrape(url) {
for (let attempt = 1; attempt <= 3; attempt++) {
const address = attempt === 1 ? url : `${url}&fresh=${Date.now()}`;
const params = new URLSearchParams({ url: address, geo: country, format: 'json' });
const response = await fetch(`https://parsing.webunlocker.gologin.com/v1/scrape?${params}`, {
headers: { apikey: process.env.GOLOGIN_SCRAPING_API_KEY },
});
const page = response.ok ? (await response.json()).data?.html : '';
if (page?.includes("key: 'ds:5'")) return page;
await new Promise((resolve) => setTimeout(resolve, 3000));
}
return '';
}
const at = (node, ...path) => path.reduce((value, step) => (Array.isArray(value) ? value[step] : undefined), node);
const appData = (page) => {
const block = page.match(/AF_initDataCallback\(\{key: 'ds:5'.*?data:(.*?), sideChannel: \{\}\}\);<\/script>/s)?.[1];
return block ? at(JSON.parse(block), 1, 2) : null;
};
const rows = [];
for (const id of apps) {
const d = appData(await scrape(`https://play.google.com/store/apps/details?id=${id}&hl=en&gl=${country.toUpperCase()}`));
rows.push({
id,
title: at(d, 0, 0),
rating: at(d, 51, 0, 1)?.toFixed(3),
ratings: at(d, 51, 2, 1),
installs: at(d, 13, 2),
version: at(d, 140, 0, 0, 0) ?? 'Varies with device',
updated: at(d, 145, 0, 0),
price: (at(d, 57, 0, 0, 0, 0, 1, 0, 0) ?? 0) / 1e6,
});
}
writeFileSync('apps.csv', ['id,title,rating,ratings,installs,version,updated,price', ...rows.map((row) => Object.values(row).map((value) => JSON.stringify(value ?? '')).join(','))].join('\n'));
console.table(rows);
console.log(`${rows.length} apps in ${rows.length} pages: $${(rows.length * 0.00098).toFixed(4)} on the Growth plan`);GOLOGIN_SCRAPING_API_KEY=your_key node google-play-rank.mjshttps://parsing.webunlocker.gologin.com/v1/scrapeconst keyword = 'meditation';
const app = 'com.calm.android';
const countries = ['us', 'gb', 'de', 'ca', 'au'];
async function scrape(url, geo) {
for (let attempt = 1; attempt <= 3; attempt++) {
const address = attempt === 1 ? url : `${url}&fresh=${Date.now()}`;
const params = new URLSearchParams({ url: address, geo, format: 'json' });
const response = await fetch(`https://parsing.webunlocker.gologin.com/v1/scrape?${params}`, {
headers: { apikey: process.env.GOLOGIN_SCRAPING_API_KEY },
});
const page = response.ok ? (await response.json()).data?.html : '';
if (page?.includes("key: 'ds:4'")) return page;
await new Promise((resolve) => setTimeout(resolve, 3000));
}
return '';
}
const results = (page) => {
const block = page.match(/AF_initDataCallback\(\{key: 'ds:4'.*?data:(.*?), sideChannel: \{\}\}\);<\/script>/s)?.[1];
const sections = block ? JSON.parse(block)?.[0]?.[1] : null;
const items = sections?.find((section) => section?.[22]?.[0])?.[22]?.[0];
return (items ?? []).map(([item]) => ({ id: item[0][0], title: item[3], rating: item[4]?.[1] }));
};
for (const country of countries) {
const found = results(await scrape(`https://play.google.com/store/search?q=${encodeURIComponent(keyword)}&c=apps&hl=en&gl=${country.toUpperCase()}`, country));
const place = found.findIndex((item) => item.id === app) + 1;
console.log(`${country.toUpperCase()}: ${app} is #${place || '-'} of ${found.length} for "${keyword}", top app: ${found[0]?.title} (${found[0]?.rating?.toFixed(1)})`);
}
console.log(`${countries.length} countries in ${countries.length} pages: $${(countries.length * 0.00098).toFixed(4)} on the Growth plan`);Ready to run it on your own apps? Get your API key and free requests.
One account, one proxy network, one ecosystem. Pick the product the job needs.
Scraping more sites? See the YouTube, Reddit and Instagram scrapers, or every web scraping tool.
A Google Play scraper, or Play Store scraper, is a tool that reads public Google Play pages and turns them into data: an app's rating, installs, version, price and reviews, or the apps a keyword search shows. Gologin's Google Play scraper API is Web Unlocker: send it an app's address and it returns the page with that data, at $0.98 per 1,000 pages.
To scrape the Google Play Store, send the app's address, play.google.com/store/apps/details?id= and the package name, to Web Unlocker with the country you want. It returns the page the way a visitor's browser loads it, with Google Play's own JSON inside: the app's details and its 20 top reviews. The code above reads it in a few lines.
Every app page carries 20 reviews with stars, text, date, helpful votes, the app version and the developer's reply, and Web Unlocker returns them with the app. Each country and language shows its own 20. For more than 20, add Cloud Browser, a separate Gologin product with its own plans: from the app page it calls Google's review feed 100 reviews at a time, newest first, and returned 2,000 of Duolingo's newest reviews in 4.5 seconds in our test.
Not for other developers' apps: there is no public Google Play Store API for them. The Google Play reviews API, part of the Google Play Developer API, works only for your own apps and returns reviews from the last week. Rating, installs, price and reviews of any other app are on its public Google Play page, which is what a Google Play scraper reads.
Send the app's address to Web Unlocker with the requests library and read Google Play's JSON from the page. The Python tab above is a complete script, tested on the live API: it prints the app's rating, ratings count, exact installs, version, price and 20 reviews.
The google-play-scraper libraries for Node.js and Python are free and read the same JSON from your own server. The Node.js author no longer maintains it and warns that it breaks when Google Play changes its pages, and heavy use from one IP gets 503 error pages for about an hour. Web Unlocker loads each page from a residential IP in the country you pick, and a page that fails costs nothing.
An app page gives the title, developer, genre, exact rating, ratings count, the count for each star, installs, price and currency, in-app price range, ads, version, update and release dates, content rating, chart place, screenshots and 20 reviews. A search page gives the apps in Google Play's order, and a data safety page what the app collects and shares.
App store optimization teams track where apps rank for a keyword in each country. Publishers watch rivals' ratings, installs, versions and prices day by day. Product and research teams read reviews for complaints and feature requests, and analysts size markets from installs and charts. The code above saves it as JSON or CSV.
Yes. Google Play shows a rounded figure such as 500M+, and keeps the exact count in the page's data: 995,744,335 for Duolingo on 11 November 2026. Web Unlocker returns both.
Yes. A keyword search page returns the apps in the order Google Play shows them, 21 to 30 for "meditation" in our test, each with its ID, title, rating, genre and price. Run the same search in several countries to see where an app ranks in each: in the Rank by country tab above, Calm is #7 in the US, #6 in Germany and #4 in Australia.
Yes. The demo offers 10 countries and the API takes any of 195+. Each country sees its own rating, prices in its own currency and reviews in its own language: Spotify is 4.17 in Germany and 4.35 in the US.
$0.98 per 1,000 pages, the same for every page: an app with its 20 reviews is one page, a search is one page. A request that fails costs nothing. Plans start at $49 a month for 50,000 requests.
Web Unlocker comes with 1,000 free requests, enough for 1,000 apps with their reviews. The open-source google-play-scraper libraries are free too: they run on your own servers and IPs, and keeping them working as Google Play changes is up to you.
Not with Web Unlocker: it brings residential IPs from 195+ countries and picks one for every request. If you run your own scraper, Gologin Proxies are the same network.
Yes. Claude and other agents call Web Unlocker like any API, and MCP & AI Skills turn a plain request, such as "compare these five apps' ratings in Germany", into a working tool.
App pages, reviews and search results on Google Play load without a Google account: they are public pages. What you collect and how you use it is your call, so check it against the rules that apply to your project, especially for reviewers' names.
Tell us a little about your team and get: