# Chrome Web Store Scraper: Extensions, Reviews & Change Tracking (`unhampered_dolly/chrome-web-store-scraper`) Actor

Scrape Chrome extensions (users, rating, version, permissions, developer) and reviews with developer replies. Monitor mode tracks changes between runs.

- **URL**: https://apify.com/unhampered_dolly/chrome-web-store-scraper.md
- **Developed by:** [Stoian Catalin](https://apify.com/unhampered_dolly) (community)
- **Categories:** Developer tools, E-commerce, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Chrome Web Store Scraper: Extensions, Reviews & Change Tracking

Get structured data on any Chrome extension: users, rating, version, last update, permissions and developer. You can also pull its reviews, including developer replies. **Monitor mode** compares each run with the previous one and shows what changed (users, rating, rating count, version), so you can watch competitors on a schedule.

### What data can you get?

| Listing field | Example |
|---|---|
| id, name, url | `kbfnbcaeplbcioakkpcpgfkobkghlhen`, Grammarly… |
| developer, developerWebsite, isTrader | Grammarly, Inc. |
| category, featured | `productivity/communication`, true |
| users, rating, ratingCount | 41000000, 3.873, 43153 |
| version, lastUpdated, size, manifestVersion | 14.1337.0, 2026-10-12, 17.56MiB, 3 |
| permissions, hostPermissions, contentScriptMatches | from the published manifest |
| languages, supportUrl, privacyPolicyUrl, description | |
| changes, hasChanged, previousScrapedAt | monitor mode only |

Review rows (`type: "review"`) contain: extensionId, reviewId, rating, text, date, updatedDate, helpfulCount, extensionVersion, language, developerReply {text, date}, and reviewerHash. **Reviewer names and developer-reply author names are never output.** `reviewerHash` is a hash with a random salt that is generated for each run and then thrown away. It lets you group reviews by the same author within one run, but it can't be linked back to a name or across runs.

### Use cases

- **Competitor tracking:** schedule a daily run in monitor mode and get alerts when a rival's user count, rating or version changes.
- **Product research:** mine 1–2★ reviews of competing extensions for feature gaps.
- **Security/compliance audits:** list the permissions and host access of the extensions your company uses.
- **Investors and market maps:** pull every featured extension in a category, with installs and ratings.

### How to use it

1. Paste extension URLs or IDs into **Extension URLs or IDs**, or add a category such as `productivity/developer`.
2. Optionally turn on **Include reviews** and choose how many reviews to get per extension.
3. To track changes, turn on **Monitor mode** and schedule the Actor (for example, daily) in Apify Console.
4. Click **Start**, then download the results as JSON, CSV or Excel, or use them through the Apify API, webhooks or integrations (Slack, Google Sheets, Zapier, Make and more).

### Input example

```json
{
  "extensionUrls": ["https://chromewebstore.google.com/detail/grammarly/kbfnbcaeplbcioakkpcpgfkobkghlhen", "nkbihfbeogaeaoehlefnkodbefgpgknn"],
  "categories": ["productivity/developer"],
  "maxItems": 5,
  "includeReviews": true,
  "maxReviewsPerExtension": 60,
  "reviewsSort": "recent",
  "monitorMode": true
}
```

### Output example

```json
{"type": "listing", "id": "nkbihfbeogaeaoehlefnkodbefgpgknn", "name": "MetaMask", "developer": "CONSENSYS SOFTWARE INC.", "category": "productivity/workflow", "users": 12000000, "rating": 2.02, "ratingCount": 5922, "version": "13.50.0", "lastUpdated": "2026-09-29T09:31:52.000Z", "permissions": ["activeTab", "alarms", "clipboardWrite", "notifications"], "changes": {"users": {"from": 11900000, "to": 12000000, "delta": 100000}}, "hasChanged": true}
{"type": "review", "extensionId": "nkbihfbeogaeaoehlefnkodbefgpgknn", "reviewId": "fe675c95-219f-4ee2-9aae-7b9858900cec", "reviewerHash": "3da1484744f303d6", "rating": 5, "text": "HAd my first issue and customer support walked me through every step in a timely fashion", "date": "2026-10-03T12:47:05.000Z", "updatedDate": "2026-10-03T12:47:05.000Z", "helpfulCount": 0, "extensionVersion": "13.50.0", "language": "en", "developerReply": {"text": "Thank you for the great feedback! We are glad to hear our Support Team was so helpful.", "date": "2026-10-06T14:08:51.000Z"}}
```

The `changes` value above is illustrative. See `sample-output.json` for a real run: 4 listings, 180 reviews and 1 error row.

### Monitor mode

Snapshots are kept in the named key-value store `monitorStoreName`, so they persist between runs. The first run marks everything `isNew`. Later runs add a `changes` object for each field that changed. Set `onlyChanged: true` to output only listings that changed.

### Good citizenship

The Actor fetches only public pages and follows robots.txt: it does not use `/search` or the `/detail/*/reviews` pages. It runs at a low rate (≤60 page requests/min, 1 s between review pages) and leaves out reviewer names, developer-reply author names and trader contact details (email, phone, address).

### Limitations

- A category page returns its ~32 featured extensions. Full category pagination and keyword search are not supported, because `/search` is disallowed by robots.txt.
- Reviews come from the same internal endpoint the Web Store page calls, so Google may change it without notice.
- Developer name comes from trader info. Non-trader developers return `developer: null`. Support email, phone and address are deliberately left out.

### Pricing

Pay per event: **$1.50 per 1,000 listings** and **$0.50 per 1,000 reviews**. Error rows (for example, an extension ID that doesn't exist) are free. Example: 50 competitor extensions with 100 reviews each costs 50 × $0.0015 + 5,000 × $0.0005 = **$2.58**. A daily monitor run on 20 extensions without reviews costs about **$0.03**. You can cap any run with the maximum cost per run setting, and the Actor stops cleanly when it reaches the cap.

### FAQ

**Is scraping the Chrome Web Store legal?** The Actor reads only public pages that robots.txt allows, at a low rate. Review text is written by people and can contain personal data. If you are subject to UK or EU GDPR, you are the controller of the data you collect: have a lawful basis (usually legitimate interests), collect only what you need and keep it only as long as you need it. Don't use the output to profile or contact individual reviewers.

**Can I get reviewer names?** No. The Actor never outputs them, by design.

**Is this an official Google product?** No. This Actor is independent and is not affiliated with, endorsed by or sponsored by Google LLC. "Chrome" and "Chrome Web Store" are trademarks of Google LLC and are used here only to describe the data source.

**Something broke?** Open an issue on the Actor's Issues tab and include the run ID.

# Actor input Schema

## `extensionUrls` (type: `array`):

Chrome Web Store detail URLs or 32-character extension IDs.

## `categories` (type: `array`):

Category paths, e.g. 'productivity/developer' or 'make_chrome_yours/privacy'. Each category page yields its ~32 featured extensions.

## `maxItems` (type: `integer`):

Maximum number of extension listings to scrape.

## `includeReviews` (type: `boolean`):

Also fetch reviews for each extension.

## `maxReviewsPerExtension` (type: `integer`):

Max reviews per extension.

## `reviewsSort` (type: `string`):

Review sort.

## `language` (type: `string`):

UI language (hl) and review language filter.

## `monitorMode` (type: `boolean`):

Compare users, rating, ratingCount and version with the previous run (stored in a named key-value store) and add a 'changes' object to each listing.

## `monitorStoreName` (type: `string`):

Named key-value store used to persist snapshots between runs.

## `onlyChanged` (type: `boolean`):

In monitor mode, skip listings that did not change (new listings count as changed).

## `maxConcurrency` (type: `integer`):

Max concurrency.

## `proxyConfiguration` (type: `object`):

Proxy configuration.

## Actor input object example

```json
{
  "extensionUrls": [
    "https://chromewebstore.google.com/detail/grammarly/kbfnbcaeplbcioakkpcpgfkobkghlhen"
  ],
  "maxItems": 50,
  "includeReviews": false,
  "maxReviewsPerExtension": 50,
  "reviewsSort": "recent",
  "language": "en",
  "monitorMode": false,
  "monitorStoreName": "chrome-web-store-monitor",
  "onlyChanged": false,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All dataset items: extension listings, reviews and error rows.

## `listings` (type: `string`):

Extension listing rows (users, rating, version, permissions, monitor-mode changes).

## `reviews` (type: `string`):

Review rows (no reviewer names; per-run reviewerHash).

## `stats` (type: `string`):

STATS record with counts of listings, reviews, changed and failed items.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "extensionUrls": [
        "https://chromewebstore.google.com/detail/grammarly/kbfnbcaeplbcioakkpcpgfkobkghlhen"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("unhampered_dolly/chrome-web-store-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "extensionUrls": ["https://chromewebstore.google.com/detail/grammarly/kbfnbcaeplbcioakkpcpgfkobkghlhen"] }

# Run the Actor and wait for it to finish
run = client.actor("unhampered_dolly/chrome-web-store-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "extensionUrls": [
    "https://chromewebstore.google.com/detail/grammarly/kbfnbcaeplbcioakkpcpgfkobkghlhen"
  ]
}' |
apify call unhampered_dolly/chrome-web-store-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,unhampered_dolly/chrome-web-store-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/pvF362BcMukdHY2LN/builds/G4id05Uh18JOfv1Wy/openapi.json
