# E-commerce Product Scraper — Price, Stock & GTIN, Any Store (`fabrikit/ecommerce-product-scraper`) Actor

Paste product, category or store URLs from almost any online shop and get name, price, currency, stock, SKU, GTIN, brand, images, rating and variants, read from schema.org data, Open Graph and Shopify JSON. Plain HTTP, no browser. From US$4.20 per 1,000 products.

- **URL**: https://apify.com/fabrikit/ecommerce-product-scraper.md
- **Developed by:** [Fabrikit](https://apify.com/fabrikit) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.20 / 1,000 product scrapeds

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

## E-commerce Product Scraper — Price, Stock & GTIN, Any Store

**E-commerce Product Scraper extracts product data from almost any online store**: name, price and currency, sale / list price, stock status, SKU, GTIN (EAN / UPC / barcode), MPN, brand, category path, images, rating, review count and the full variant list (size, colour…). Paste product pages, category or collection pages, or just a store's home page — one Actor works across Shopify, WooCommerce, BigCommerce, Salesforce Commerce Cloud and custom-built shops.

It reads the **structured data stores publish for Google Shopping and search engines** (schema.org JSON-LD, microdata, Open Graph product tags) and, on Shopify, the public product JSON. No browser, no CSS selectors to maintain, no AI guessing: the values come from the store's own markup. It is built on the HTTP crawling core of our [Website to Markdown Scraper](https://apify.com/fabrikit/website-to-markdown-scraper) (fetching, robots.txt, sitemaps).

### What you get for each product

| Field | Example |
|---|---|
| `name`, `brand`, `description` | Men's Tree Runner - Jet Black (White Sole), Allbirds |
| `price`, `maxPrice`, `listPrice`, `onSale`, `currency` | 100, 100, null, false, USD |
| `availability`, `inStock` | InStock, true |
| `sku`, `gtin`, `mpn`, `productId` | TR3MJBW080, 843416184854 |
| `category`, `breadcrumbs` | Men's > Fleece > Jackets |
| `image`, `images` | main picture + gallery (largest size) |
| `rating`, `reviewCount` | 4.6, 9951 |
| `variants` | each with its own SKU, GTIN, price, stock flag, options and URL |
| `store`, `platform`, `dataSources` | allbirds.com, shopify, json-ld + shopify-json |

Prices are numbers, dates are ISO 8601, availability uses the schema.org names (`InStock`, `OutOfStock`, `PreOrder`, `BackOrder`…). Reviews and reviewer names are never collected.

### Use cases

- **Price monitoring and MAP compliance** — schedule the Actor on your competitors' or resellers' product pages and track price, sale price and stock every day.
- **Catalog and feed enrichment** — fill GTIN, brand, images and descriptions for products you list, or match your SKUs to other shops by barcode.
- **Market research** — collect a whole category from several stores and compare prices, ranges and ratings.
- **AI agents and RAG** — give an LLM clean, structured product facts instead of raw HTML.

### How it works

1. **Product page** → one row. Sources are merged: JSON-LD `Product` / `ProductGroup` (with `hasVariant` or `isVariantOf`), `Offer` / `AggregateOffer` / `priceSpecification`, `AggregateRating`, `BreadcrumbList`; then microdata; then Open Graph `product:` tags. On Shopify the Actor also reads `/products/<handle>.js` for every variant's SKU, barcode, price, compare-at price and stock flag.
2. **Category, collection, search or home page** → the Actor finds the product links (JSON-LD `ItemList`, microdata product cards, the product grids of common store themes, product-looking links) and follows "next page" links up to `maxListingPages`. Links that turn out not to be products are skipped and never charged. Shopify collections and home pages are listed through `/products.json` (250 products per request).
3. **Sitemaps** (optional) → `useSitemaps` reads the store's product sitemap for a whole catalog. Home pages without product links use it automatically.

Requests are polite: robots.txt is respected by default, each store gets at most 2 requests at a time with a pause between them, and several stores are processed in parallel. When a store answers with an anti-bot page, the request is retried with other browser header profiles (Chrome, Firefox, Safari).

### Input example

```json
{
    "startUrls": [
        { "url": "https://www.allbirds.com/products/mens-tree-runners" },
        { "url": "https://www.ikea.com/us/en/cat/billy-bookcases-58288/" },
        { "url": "https://scrapeme.live/shop/" }
    ],
    "maxItems": 100,
    "maxListingPages": 3,
    "includeVariants": true
}
```

### Output example

```json
{
    "url": "https://www.allbirds.com/products/mens-tree-runners",
    "store": "allbirds.com",
    "platform": "shopify",
    "name": "Men's Tree Runner - Jet Black (White Sole)",
    "brand": "Allbirds",
    "price": 100,
    "maxPrice": 100,
    "listPrice": null,
    "onSale": false,
    "currency": "USD",
    "availability": "InStock",
    "inStock": true,
    "sku": "MENS_TREE_RUNNERS",
    "productId": "4870548979792",
    "condition": "New",
    "image": "https://cdn.shopify.com/s/files/1/1104/4168/files/TR3MJBW080_SHOE_LEFT_GLOBAL_MENS_TREE_RUNNER_JET_BLACK_WHITE.png?v=1751165486",
    "rating": 4.6,
    "reviewCount": 9951,
    "productType": "Shoes",
    "variantsCount": 7,
    "variants": [
        {
            "name": "Men's Tree Runner - Jet Black (White Sole) - 8",
            "sku": "TR3MJBW080",
            "gtin": "843416184854",
            "price": 100,
            "currency": "USD",
            "availability": "InStock",
            "inStock": true,
            "stockQuantity": 42,
            "options": { "Size": "8" },
            "url": "https://www.allbirds.com/products/mens-tree-runners?variant=33179624669264"
        }
    ],
    "dataSources": ["json-ld", "shopify-json"],
    "inputUrl": "https://www.allbirds.com/products/mens-tree-runners",
    "status": "ok",
    "scrapedAt": "2026-10-21T05:31:58.114Z"
}
```

A start URL that gives no product gets a free row with `status` (`blocked`, `not-found`, `no-product-data`, `robots-disallowed`, `timeout`…) and an `error` message, so you always know why. Turn it off with `saveFailedUrls: false`.

### Pricing

Pay per event: **US$4.20 per 1,000 products** (US$0.0042 per product row). Platform usage is included.

- 100 products → US$0.42
- 1,000 products → US$4.20
- 10,000 products → US$42

Status rows for failed start URLs, listing pages, sitemap reads and Shopify JSON requests are free. `maxItems` is exact and the run stops at your maximum charge per run.

### How it compares

- **apify/e-commerce-scraping-tool** charges US$6.00 per 1,000 products on the free plan and also covers marketplaces and keyword search. This Actor is about 30 % cheaper for product, category and store URLs you already have, and returns variants, GTIN and stock per variant when the store publishes them.
- For a **full Shopify or WooCommerce catalog**, our [Shopify Store Products Scraper](https://apify.com/fabrikit/shopify-store-products-scraper) and [WooCommerce Store Products Scraper](https://apify.com/fabrikit/woocommerce-store-products-scraper) read the store APIs in bulk for less. Use this Actor when stores are mixed or you need ratings, breadcrumbs and GTIN.

### Integrations

Run it from the [Apify API](https://docs.apify.com/api/v2) or a client library, on a schedule, or from **n8n, Make, Zapier**, Google Sheets and webhooks. AI agents can call it through the Apify MCP server and get JSON back.

### FAQ

**Is it legal?** It reads publicly available product pages — the same structured data stores publish for search engines — and respects robots.txt by default. Check each store's terms for your use case. No personal data is collected.

**Which stores work?** Stores that publish schema.org Product data, microdata or Open Graph product tags in their HTML — most Shopify, WooCommerce and BigCommerce shops and many big brands do. Tested on Allbirds (Shopify), IKEA, nutribullet, the ScrapeMe (WooCommerce), BigCommerce and Web Scraper demo stores, and on LEGO and Patagonia, which only answered to some browser header profiles. Pages that render products with JavaScript only, or that sit behind strong anti-bot protection, return a free `no-product-data` or `blocked` row.

**Do I need a proxy?** The Apify datacenter proxy (default) is enough for most stores. Apify Residential is not offered because product pages are heavy; if a store blocks datacenter IPs you can add your own proxy URLs.

**Why is a field empty?** Fields are only filled when the store publishes them. Many stores omit GTIN or rating, for example.

### Changelog

- **0.1 (October 2026)** — First release: JSON-LD, microdata, Open Graph and Shopify product JSON; listing pages, pagination, Shopify collections and product sitemaps; variants with GTIN and stock.

### En español

**E-commerce Product Scraper** extrae nombre, precio, moneda, stock, SKU, GTIN/EAN, marca, imágenes, valoración y variantes de páginas de producto de casi cualquier tienda online (Shopify, WooCommerce, BigCommerce, Salesforce y tiendas propias), leyendo los datos estructurados schema.org que la tienda publica. Acepta páginas de producto, de categoría o la portada de la tienda. Cuesta US$4,20 por cada 1.000 productos; las filas de URLs que fallan son gratis.

# Actor input Schema

## `startUrls` (type: `array`):

Product pages (one row each), or category, collection, search and home pages (the Actor finds the product links on them). Mix stores freely. Left empty, the four example products below are scraped.

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

Stop after this many products have been saved (exact). Rows explaining why a start URL gave no product are extra and free. 0 = no limit.

## `followProductLinks` (type: `boolean`):

When a start URL is not a product page (category, collection, search results, home page), collect the product links on it and scrape them. Off = only product pages are read.

## `maxListingPages` (type: `integer`):

How many pages of a category / collection to walk through its "next page" link (Shopify collections: pages of 250 products).

## `useSitemaps` (type: `boolean`):

Also take product URLs from the store's sitemap (robots.txt Sitemap lines, product sitemaps first). Good for a whole catalog; set Max products to keep the run bounded. Home pages without product links use the sitemap automatically.

## `includeVariants` (type: `boolean`):

List the variants (size, colour...) with their own SKU, GTIN, price and stock, when the store publishes them.

## `maxVariantsPerProduct` (type: `integer`):

Cap on the variants array of one product.

## `includeDescription` (type: `boolean`):

Product description as plain text (up to 5,000 characters).

## `shopifyVariantData` (type: `boolean`):

On Shopify stores, also read /products/<handle>.js: every variant with SKU, barcode (GTIN), price, compare-at price and stock flag, plus product type and tags. One extra small request per product.

## `saveFailedUrls` (type: `boolean`):

Add a free row with status and error for each start URL that gave no product (blocked, not found, no structured data, robots.txt).

## `respectRobotsTxt` (type: `boolean`):

Skip pages the store's robots.txt disallows.

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

Pages read at the same time across all stores (each store gets at most 2 at once, with a short pause between requests).

## `acceptLanguage` (type: `string`):

Language / region sent to the stores (e.g. en-US, de-DE, es-CL). Some stores pick the currency and language from it.

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

Apify datacenter proxy by default, with a new session per request. Apify Residential is not available in this Actor; to use residential IPs, add your own proxy under Proxy URLs.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.allbirds.com/products/mens-tree-runners"
    },
    {
      "url": "https://www.ikea.com/us/en/p/billy-bookcase-white-20522046/"
    },
    {
      "url": "https://scrapeme.live/shop/Bulbasaur/"
    },
    {
      "url": "https://cornerstone-light-demo.mybigcommerce.com/all/orbit-terrarium-large/"
    }
  ],
  "maxItems": 20,
  "followProductLinks": true,
  "maxListingPages": 3,
  "useSitemaps": false,
  "includeVariants": true,
  "maxVariantsPerProduct": 100,
  "includeDescription": true,
  "shopifyVariantData": true,
  "saveFailedUrls": true,
  "respectRobotsTxt": true,
  "maxConcurrency": 6,
  "acceptLanguage": "en-US",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `products` (type: `string`):

All product and status rows saved during the run

## `summary` (type: `string`):

Products saved, pages read, platforms seen, statuses of failed URLs and HTTP counters

# 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 = {
    "startUrls": [
        {
            "url": "https://www.allbirds.com/products/mens-tree-runners"
        },
        {
            "url": "https://www.ikea.com/us/en/p/billy-bookcase-white-20522046/"
        },
        {
            "url": "https://scrapeme.live/shop/Bulbasaur/"
        },
        {
            "url": "https://cornerstone-light-demo.mybigcommerce.com/all/orbit-terrarium-large/"
        }
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("fabrikit/ecommerce-product-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 = {
    "startUrls": [
        { "url": "https://www.allbirds.com/products/mens-tree-runners" },
        { "url": "https://www.ikea.com/us/en/p/billy-bookcase-white-20522046/" },
        { "url": "https://scrapeme.live/shop/Bulbasaur/" },
        { "url": "https://cornerstone-light-demo.mybigcommerce.com/all/orbit-terrarium-large/" },
    ],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("fabrikit/ecommerce-product-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 '{
  "startUrls": [
    {
      "url": "https://www.allbirds.com/products/mens-tree-runners"
    },
    {
      "url": "https://www.ikea.com/us/en/p/billy-bookcase-white-20522046/"
    },
    {
      "url": "https://scrapeme.live/shop/Bulbasaur/"
    },
    {
      "url": "https://cornerstone-light-demo.mybigcommerce.com/all/orbit-terrarium-large/"
    }
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call fabrikit/ecommerce-product-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fabrikit/ecommerce-product-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/fQ2RAnXsNRfwWZ5aa/builds/agHWRu2b0yyPfPX4V/openapi.json
