# Chrome Web Store Scraper: Extension Users & Ratings (`spbros/chrome-web-store-extension-scraper`) Actor

Extract public Chrome Web Store extension data: users, rating, rating count, version, last updated, size, languages, category and developer name. Robots.txt-compliant, no login, no personal data.

- **URL**: https://apify.com/spbros/chrome-web-store-extension-scraper.md
- **Developed by:** [Hansol Jung](https://apify.com/spbros) (community)
- **Categories:** Developer tools, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 extension results

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: Extension Users & Ratings

Extract structured data from public **Chrome Web Store** extension pages: user count, star rating, number of ratings, version, last-updated date, size, languages, category, developer name, badges and full description. Discover extensions from category pages or paste your own list of URLs/IDs.

### Why use it

- **Market research**: size a niche by summing users across a category.
- **Competitor monitoring**: track version bumps, rating drift and user growth of rival extensions on a schedule.
- **Lead lists for extension builders and investors**: find fast-growing extensions with high ratings.
- **Cheap**: pay only per extension scraped — no monthly rental.

### What data you get

| Field | Example |
|---|---|
| name | uBlock Origin Lite |
| users | 21000000 |
| rating / ratingCount | 4.5 / 3700 |
| version / updated | 2026.1012.1545 / October 13, 2026 |
| size | 8.7MiB |
| category | Privacy & Security |
| developerName | Raymond Hill (gorhill) |
| languagesCount | 60 |
| isFeatured, followsRecommendedPractices, isTrader | true, true, false |
| shortDescription, description, iconUrl, url, id, scrapedAt | … |
| categoryPath / discoveredVia | extensions/productivity/tools / category |

### How to use

1. Add extension URLs (`https://chromewebstore.google.com/detail/name/ID`) or bare 32-character IDs, **and/or** category URLs such as `https://chromewebstore.google.com/category/extensions/productivity/tools`.
2. Set **Max items** to cap cost.
3. Run and download results as JSON, CSV, Excel or via API.

#### Example input

```json
{
  "extensionUrls": ["nngceckbapebfimnlniiiahkandclblb"],
  "categoryUrls": ["extensions/productivity/tools"],
  "maxItemsPerCategory": 30,
  "maxItems": 100
}
```

#### Related discovery and manifests (opt in)

`followRelated` (default `false`) extracts other 32-character extension IDs from raw detail HTML **before scripts are removed**. A deduplicated FIFO work queue processes category seeds first, then direct input seeds, then related discoveries breadth-first, under the existing concurrency semaphore and `maxItems` cap. With this flag off, the original input-first order is preserved. `categoryPath` is the discovery category slug, or null for a direct input; related items inherit their parent's slug. `discoveredVia` is `input`, `category`, or `related`. Existing per-result `extension-result` charging is unchanged.

`includeManifest` (default `false`) fetches the public CRX with redirects. It first requests the final 65,536 bytes, reads the ZIP end/central directory, computes the ZIP start within the CRX prefix, and requests only the manifest's local header and compressed bytes. Stored and raw-DEFLATE entries are supported. Servers that ignore ranges fall back to a full download capped at 60 MiB. HTTP 204 means unavailable; individual manifest failures do not discard store metadata. JSON accepts UTF-8 BOMs and, on strict parse failure, comments outside strings and trailing commas.

Manifest output: `manifestVersion`, `permissions`, `optionalPermissions`, `hostPermissions`, `optionalHostPermissions`, `contentScriptMatches` (unique content-script matches), and `manifestError` (null on success, a short error string otherwise). MV2 URL patterns are moved out of permissions into the respective required/optional host arrays. These fields are emitted only when manifest collection is enabled.

```json
{
  "categoryUrls": ["extensions/productivity/tools"],
  "maxItemsPerCategory": 40,
  "maxItems": 2000,
  "maxConcurrency": 5,
  "followRelated": true,
  "includeManifest": true
}
```

Offline range-parser tests build local CRX-like fixtures (prefix + ZIP) with a fake fetcher. No Apify credentials or network are needed:

```sh
python3 -m unittest discover -s tests -v
```

### Pricing

Pay-per-event: **$0.002 per extension** returned (1,000 extensions = $2). No start fee. Platform usage is included.

### Compliance

- Public store detail/category pages are used for metadata. Opt-in manifest collection also requests Google's public CRX update/CDN service. Reviews, search, support and privacy subpages are **not** crawled.
- Developer e-mail addresses and other personal data are **deliberately not collected**.
- Polite concurrency and back-off are built in.

### FAQ

**Does it need a Google login or proxy?** No.
**Can I schedule it?** Yes — use Apify Schedules to track changes daily/weekly.
**Something broke?** Open an issue on the Actor's Issues tab; fixes are usually shipped within 48 hours.

# Actor input Schema

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

Chrome Web Store detail URLs (https://chromewebstore.google.com/detail/name/ID) or bare 32-character extension IDs.

## `categoryUrls` (type: `array`):

Chrome Web Store category pages to discover extensions from, e.g. https://chromewebstore.google.com/category/extensions/productivity/tools or extensions/productivity/tools.

## `maxItemsPerCategory` (type: `integer`):

How many extensions to take from each category page (a page lists about 30).

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

Hard cap on results (and cost).

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

Parallel requests. Keep low to be polite.

## `followRelated` (type: `boolean`):

Discover IDs in raw detail HTML, including scripts. Breadth-first, deduplicated, capped by maxItems.

## `includeManifest` (type: `boolean`):

Read manifest.json from CRX byte ranges, with a bounded 60 MB full-download fallback.

## Actor input object example

```json
{
  "extensionUrls": [
    "https://chromewebstore.google.com/detail/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh",
    "nngceckbapebfimnlniiiahkandclblb"
  ],
  "categoryUrls": [
    "https://chromewebstore.google.com/category/extensions/productivity/tools"
  ],
  "maxItemsPerCategory": 30,
  "maxItems": 100,
  "maxConcurrency": 3,
  "followRelated": false,
  "includeManifest": false
}
```

# Actor output Schema

## `overview` (type: `string`):

Results in the default dataset (Overview view).

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

No description

# 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/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh",
        "nngceckbapebfimnlniiiahkandclblb"
    ],
    "categoryUrls": [
        "https://chromewebstore.google.com/category/extensions/productivity/tools"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("spbros/chrome-web-store-extension-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/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh",
        "nngceckbapebfimnlniiiahkandclblb",
    ],
    "categoryUrls": ["https://chromewebstore.google.com/category/extensions/productivity/tools"],
}

# Run the Actor and wait for it to finish
run = client.actor("spbros/chrome-web-store-extension-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/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh",
    "nngceckbapebfimnlniiiahkandclblb"
  ],
  "categoryUrls": [
    "https://chromewebstore.google.com/category/extensions/productivity/tools"
  ]
}' |
apify call spbros/chrome-web-store-extension-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,spbros/chrome-web-store-extension-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/4otKS2hbU5PxdhNEk/builds/a0MKcURyTmQN6Prcf/openapi.json
