# Chrome Web Store Scraper: Extension Details & Discovery (`winterlock/chrome-web-store-scraper`) Actor

Pull name, description, rating, rating count, user count, version, size and last-updated date for any Chrome extension, and discover extensions through the store's own XML sitemap. Respects the store's robots.txt. No login or API key.

- **URL**: https://apify.com/winterlock/chrome-web-store-scraper.md
- **Developed by:** [Alex Burton](https://apify.com/winterlock) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 extension with full details

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 Details & Discovery

Full public metadata for any Chrome extension, plus a way to discover extensions through the store's own sitemap. No Google account, API key or browser needed.

| Mode | What you get |
|---|---|
| **Extension details** | Name, description, icon, developer, star rating, rating count, user count, version, size and last-updated date |
| **Discover via sitemap** | Extension IDs and store URLs read from the Chrome Web Store's published XML sitemap, optionally with full details for each |

### Why use this one

- **It respects the store's rules.** The Chrome Web Store's `robots.txt` disallows `/search` and `/detail/*/reviews`. This Actor implements neither. Discovery instead uses the XML sitemap that the same `robots.txt` publishes for crawlers. If you need an extension scraper you can point at without an argument from your legal team, this is the one.
- **Built to survive redesigns.** The store publishes no structured-data block, so most scrapers hard-code CSS classes and break within weeks. This one reads the Open Graph meta tags Google keeps stable for link previews, and finds the numbers in the page's visible text after stripping markup.
- **Honest about gaps.** Fields that cannot be read come back `null` rather than silently wrong, and the log says which pages returned nothing.
- **Track your own extension.** Schedule it daily against your extension ID to chart users, rating and version over time.

### How to use it

1. Choose **What to scrape**.
2. For details, add **Extensions** — store links or bare 32-character IDs.
3. For discovery, optionally set **Sitemap shards** and turn on **Load full details** if you want more than IDs and URLs.
4. Click **Start**, then download results as JSON, CSV, Excel or HTML, or fetch them through the Apify API.

Extensions can be given in either form:

```
https://chromewebstore.google.com/detail/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh
ddkjiahejlhfcafbddmgiahcphecmpfh
```

#### Example input: track a set of extensions

```json
{
  "mode": "extensionDetails",
  "extensions": [
    "ddkjiahejlhfcafbddmgiahcphecmpfh",
    "https://chromewebstore.google.com/detail/grammarly/kbfnbcaeplbcioakkpcpgfkobkghlhen"
  ]
}
```

#### Example input: discover 500 extensions cheaply

```json
{
  "mode": "sitemap",
  "sitemapShards": ["0", "1"],
  "maxResults": 500,
  "fetchDetails": false
}
```

### Output

**Extension**

```json
{
  "type": "extension",
  "extensionId": "ddkjiahejlhfcafbddmgiahcphecmpfh",
  "name": "uBlock Origin Lite",
  "description": "An efficient, lean content blocker.",
  "url": "https://chromewebstore.google.com/detail/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh",
  "iconUrl": "https://lh3.googleusercontent.com/…=s128-rj-sc0x00ffffff",
  "developer": "Raymond Hill (gorhill)",
  "rating": 4.5,
  "ratingCount": 3700,
  "users": 21000000,
  "version": "2026.1012.1545",
  "size": "8.7MiB",
  "updatedOn": "2026-10-12T00:00:00Z"
}
```

**Discovered link** (when *Load full details* is off)

```json
{
  "type": "extensionLink",
  "extensionId": "ddkjiahejlhfcafbddmgiahcphecmpfh",
  "url": "https://chromewebstore.google.com/detail/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh",
  "sourceSitemap": "https://chromewebstore.google.com/sitemap?shard=0"
}
```

### What this can and cannot reach

Checked against the store's own `robots.txt` and sitemap in October 2026:

- **The sitemap works and covers the whole store.** The index lists 45 shards,
  each full of `/detail/<slug>/<id>` URLs. Sitemap mode walks them in order until
  your limit is reached, so discovery is not capped at one shard or one category.
- **Extension pages are fair game** and carry the detail this Actor reads.
- **Search and the per-extension review pages are disallowed** by the store's
  `robots.txt` (`/search`, `/detail/*/reviews`), so they are not implemented here.
- **Category pages** render their listings client-side, so a plain fetch returns
  no extensions; the sitemap is the reliable way to enumerate.

The practical workflow is therefore: walk the sitemap to discover extensions, then
turn on **Fetch full details** to enrich them. Discovery is billed at a fraction of
the enriched rate, so you can enumerate the store cheaply and pay the detail rate
only for what you keep.

### Pricing

| Result | Price |
|---|---|
| Extension with full details | $5.00 per 1,000 |
| Discovered link (no details) | $0.50 per 1,000 |

Set a maximum spend per run in the run options and the Actor stops cleanly when it's reached.

### Limits to know about

- **No search mode and no reviews mode.** Both paths are disallowed by the store's `robots.txt`, so this Actor does not touch them. If you need extension reviews, the store does not offer a crawlable source for them.
- **Rating, rating count, users, version, size and updated date are best-effort.** They are parsed from the page's visible text because the store publishes no structured data. Name, description, icon, ID and URL come from meta tags and are reliable. Any field that cannot be read is `null`. An extension nobody has rated returns `rating: null` and `ratingCount: 0`, and `developer` is `null` when the developer publishes only a website or email link rather than a name.
- **Rating counts are rounded by the store itself.** The page shows figures like "43.2K ratings", so `ratingCount` is `43200`, not an exact number.
- **Discovery starts slowly.** Each sitemap shard is a large XML file, so the first results of a Sitemap run arrive after about a minute. After that, links are collected almost instantly; detail pages cost one request each.
- **Category pages are not supported.** The store renders them in the browser, so they contain no extension links for a crawler to read.
- Google rate-limits heavy scraping by IP. Turn on Apify Proxy for large discovery runs.

### FAQ

**Do I need a Google account?** No. Everything comes from public pages, with no sign-in.

**Why can't I search for extensions by keyword?** The store's `robots.txt` disallows `/search`. Use sitemap discovery and filter the results yourself, or supply the IDs you care about.

**Why is `users` a round number?** The store itself reports rounded user counts such as "21,000,000 users". That is the published figure, not an estimate this Actor made.

**Can I watch my own extension's rating over time?** Yes. Put your extension ID in and create a daily schedule in Apify Console. Each run appends a dated row.

**Is this legal?** The Actor reads publicly available pages, does not log in, does not bypass any protection, and stays within the paths the store's `robots.txt` permits. Google's terms restrict automated access generally, so review them for your use case.

### Feedback

Found a bug or need a field that's missing? Open an issue on the Actor's **Issues** tab.

# Actor input Schema

## `mode` (type: `string`):

Details for extensions you name, or discovery of extensions through the store's XML sitemap.

## `extensions` (type: `array`):

Store links (https://chromewebstore.google.com/detail/name/abcdefghijklmnopabcdefghijklmnop) or bare 32-character extension IDs.

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

Two-letter language code for the store page, such as en, es, de.

## `sitemapShards` (type: `array`):

Optional. Specific shard numbers to read, such as 0, 1, 2. Leave empty to walk all of the store's shards in order until Max results is reached.

## `maxResults` (type: `integer`):

How many extensions to collect in Sitemap mode. The whole store runs to hundreds of thousands, so this is the main control on run size and cost.

## `fetchDetails` (type: `boolean`):

Off returns just the store URL and ID, which is fast and cheap. On loads every extension's page for its rating, users and version, which costs one request each.

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

Stop the run after saving this many items. Leave empty for no limit.

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

Lower this if you see rate-limit retries in the log.

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

Google rate-limits heavy scraping by IP. Turn on Apify Proxy for large discovery runs.

## Actor input object example

```json
{
  "mode": "extensionDetails",
  "extensions": [
    "ddkjiahejlhfcafbddmgiahcphecmpfh"
  ],
  "language": "en",
  "maxResults": 100,
  "fetchDetails": false,
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `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 = {
    "extensions": [
        "ddkjiahejlhfcafbddmgiahcphecmpfh"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("winterlock/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 = { "extensions": ["ddkjiahejlhfcafbddmgiahcphecmpfh"] }

# Run the Actor and wait for it to finish
run = client.actor("winterlock/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 '{
  "extensions": [
    "ddkjiahejlhfcafbddmgiahcphecmpfh"
  ]
}' |
apify call winterlock/chrome-web-store-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,winterlock/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/26cWcy75knp5PQz6F/builds/EEQtbZKkgG32Y5Iex/openapi.json
