Google Play Chart History — Rank Movement & Entries/Exits avatar

Google Play Chart History — Rank Movement & Entries/Exits

Pricing

from $0.05 / 1,000 results

Go to Apify Store
Google Play Chart History — Rank Movement & Entries/Exits

Google Play Chart History — Rank Movement & Entries/Exits

Historical Google Play top-chart rankings for Pakistan, India & UAE — track app rank movement, new entries, and exits over time. Built for competitor tracking, ASO research, and regional market intelligence. Facts only: no reviews, no personal data, updated nightly.

Pricing

from $0.05 / 1,000 results

Rating

0.0

(0)

Developer

Behram Khan

Behram Khan

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

20 minutes ago

Last modified

Categories

Share

Google Play Chart History — Actor #2

What this sells that play-charts-scraper (Actor #1) cannot: what the chart was, not what it is now. A live scraper can answer "what's on the PK top chart right now" by fetching a page. It cannot answer "what has been happening to it" — no fetch produces the past. This Actor reads the nightly archive play-charts-scraper has been building at ~/ghost-archive/ on ghostlab since 2026-08-26, and derives rank movement, entries, exits, and coverage-aware deltas from it.

Makes zero live requests. No proxy, no new robots.txt question, no new ToS exposure — see ../../monetization/legal-gate.md, "Google Play chart history" entry. Full build rationale, architecture decision, and phased plan: ../../../../shared/07-plans/actor-2-rank-history-plan.md.

Architecture — baked image, not a live push

The archive is copied into the Docker image at build time, not fetched live and not pushed nightly from ghostlab. Deliberate: this project's characteristic failure is unattended jobs dying silently (the scraper itself did, for three nights, in the 2026-08-29 restructure). A push pipeline would add exactly that risk to the revenue path. History is stale-tolerant by nature — a customer asking about August doesn't care if the image is a day or a week old — so the cost of not running a live sync is near zero, and the benefit is one less unattended job that can fail without anyone knowing.

Before building the image, sync a fresh copy of the archive:

PREREQ SSH access to ghostlab
COMMAND rsync -avz ghostlab:~/ghost-archive/archive/ \
projects/A-data-business/code/play-rank-history/archive/
VERIFY ls archive/ shows year/month subdirectories with .parquet files;
a stale or empty archive/ here means a stale or empty product —
there is no live fallback.

Coverage is measured at run time, never hardcoded

src/history.py::measure_coverage() reads every Parquet file's collected_at column on every run and reports the real first date, last date, and every missing date. Nothing in this Actor's code assumes a specific coverage window — the moment it did, a rebuilt image with more data would silently carry a stale, wrong claim forward. Any request outside the measured window fails loudly with the actual window named in the error, rather than returning a shorter answer than what was asked for.

[VERIFIED 2026-09-03, real archive] Measured live: archive spans 2026-08-26 to 2026-09-03, 12,098 rows across 7 files, and the only genuinely missing dates are 30 Aug and 31 Aug (lost permanently — a snapshot is a point-in-time observation and cannot be backfilled). This also corrected a KB-wide error: CURRENT-STATE.md had listed "1 Sep" as a third lost night, but the archive holds real data for that date — the scheduled 02:00 cron attempt failed that night, but a same-day manual rerun recovered it. 3 consecutive clean days as of this measurement (1-3 Sep). Do not list this as a "history" product until a real run reports at least 30 consecutive clean days — see the build plan §5 C3 for the reasoning. A "movement" framing (what changed in the last N days) is honest at any archive age; the word "history" is not.

Fields

FieldNotes
rank_delta_1d / rank_delta_7dPositive = moved up (lower rank number). Null, not computed, across any archive gap — never guess across a missing night.
days_on_chartCount of archive dates the app appears in first_seen..last_seen, not calendar days — a gap reduces this honestly.
coverage_missing_daysNon-zero means treat the deltas and day-count around it as a floor, not exact. Surface this to the buyer; do not strip it out for a cleaner-looking row.

What's deliberately excluded

Same scope boundary as Actor #1, inherited rather than re-decided: developer name, review text, icons, screenshots, prices. See ../../monetization/legal-gate.md Q2/Q3.

Status

Built and verified against the real archive on ghostlab 2026-09-03 (Docker image, 206MB, real coverage measurement, real history rows produced). Not yet pushed to Apify — needs an authenticated apify login session, not SSH. Not yet listed — gated on the operator's Telegram/ntfy decision (A1) and on the archive reaching 30 consecutive clean days (C3). Full detail in the build plan §7.