# WooCommerce Products Scraper - Export Prices, Stock & CSV (`tinyrex/woocommerce-products-scraper`) Actor

WooCommerce products scraper: export prices, sale prices, variations, SKUs, stock and images to CSV/JSON. Filter by price, stock or minimum discount % (filtered free). Price monitoring built in. $0.60 per 1,000 products; non-WooCommerce, blocked or filtered results free.

- **URL**: https://apify.com/tinyrex/woocommerce-products-scraper.md
- **Developed by:** [TinyRex](https://apify.com/tinyrex) (community)
- **Categories:** E-commerce, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.48 / 1,000 products

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## WooCommerce Products Scraper: export products, prices, variations and stock to CSV

**WooCommerce products scraper: export every product from any WooCommerce store to CSV, Excel or JSON.** Enter a store domain, a category URL or a product URL and get prices, sale prices, discount %, variations (size, color) with their own SKU, price and stock, plus categories, tags, brands, ratings, images and descriptions. Filter by price, stock, sale or a minimum discount %. It reads the store's public WooCommerce **Store API** (no browser, no login) and respects `robots.txt`. **$0.60 per 1,000 products, variation details included; non-WooCommerce or blocked sites and products removed by your filters are free.**

### What you get from the WooCommerce Products Scraper

- **The full catalog of any WooCommerce store**: product ID, SKU, title, type, price, max price, regular and sale price, discount %, currency, stock status and stock text ("12 in stock"), rating and review count, categories, tags, brands, attributes, images, weight, dimensions and description.
- **Full variation data at no extra cost**: price, regular price, SKU and stock for every variation, nested in the product or as **one row per variation** (flat, best for spreadsheets and price tracking).
- **Price and new-product monitoring built in**: schedule it with *Monitoring mode* and each run returns only new products, or new products plus **price and stock changes** with the previous values.

### Sample output (JSON)

```json
{
  "storeName": "Mandarin Stone",
  "productId": 499641,
  "url": "https://www.mandarinstone.com/product/terrazzo-ivory-honed/",
  "title": "Terrazzo Ivory Honed",
  "type": "variable",
  "price": 0.66,
  "maxPrice": 13.68,
  "currency": "GBP",
  "inStock": true,
  "categories": ["All Terrazzo", "New arrivals"],
  "attributes": [{ "name": "Size", "values": ["200x200x12", "200x50x12", "406x406x18"], "usedForVariations": true }],
  "variationsCount": 4,
  "variations": [{ "id": 500195, "title": "Size: 200x50x12", "sku": "TCTEIVOSC20X5", "price": 0.66, "inStock": true, "stockText": "4094 in stock" }],
  "featuredImage": "https://www.mandarinstone.com/app/uploads/2026/08/Terrazzo-Ivory-Honed-scaled.jpg"
}
```

Download as **JSON, CSV, Excel or HTML**, or send it to Google Sheets, Make, Zapier, n8n, Slack, webhooks or the Apify API. Each run also writes a `STORES` report (status per input: `ok`, `not_woocommerce`, `blocked`, `disallowed_by_robots`, `unreachable`, `not_found`, `error`, plus store name, currency and product counts) and a `SUMMARY` record to the key-value store.

### How to configure the WooCommerce Products Scraper

1. Add **WooCommerce stores, categories or products** (one per line): a domain (`nalgene.com`), a category (`https://nalgene.com/product-category/accessories/`, custom category URLs work too) or a single product (`https://nalgene.com/product/four-wheeling-sticker/`).
2. Optional: a **search query** (the store's own search, fastest for big stores), keywords, exclude keywords, categories, brands, price range, only in stock, only on sale, or a minimum discount %.
3. Pick **products** or **variations** output, then run, or schedule it with *Monitoring mode* on.

#### Example input: in-stock products from two stores

```json
{
  "stores": ["https://nalgene.com", "https://www.mandarinstone.com/collections/all-terrazzo/"],
  "outputMode": "products",
  "onlyInStock": true,
  "maxProductsPerStore": 500
}
```

| Setting | Default | Notes |
|---|---|---|
| stores | `https://nalgene.com`, `mandarinstone.com` | Store domain, category URL or product URL |
| maxProductsPerStore | 100 | `0` = all products; newest first |
| outputMode | products | `products` (variations nested) or `variants` (one row per variation) |
| search | empty | Uses the store's own product search |
| keywords / excludeKeywords | none | Match title, SKU, categories, tags or brands |
| categories / brands | none | Partial match (name or slug) |
| minPrice / maxPrice | 0 (no limit) | In the store currency |
| onlyInStock / onlyOnSale | false | In-stock only / discounted only |
| minDiscountPercent | 0 (off) | Keep products whose discount is at least this %; below the cut is free |
| includeVariations | true | Variation price, SKU and stock; costs nothing extra |
| descriptionFormat | text | `text`, `html`, `both` or `none` |
| monitorMode / stateKey | off / default | `new` or `changes`; use one state key per schedule |
| maxConcurrency | 5 | Stores in parallel; lower it if a store rate-limits |
| proxyConfiguration | no proxy | Turn on Apify Proxy if a store blocks or rate-limits |

### Common use cases

- **Competitor price monitoring**: track a rival WooCommerce shop's prices, sale prices and stock daily and get only the changes.
- **Supplier and dropshipping catalogs**: pull a supplier's full catalog with SKUs, variations and images into a spreadsheet or your own store.
- **Ecommerce market research**: catalog size, price ranges, brands and categories across many independent shops.
- **Lead generation for WooCommerce agencies and plugin makers**: find shops by niche, size or catalog quality, then reach out.

### Pricing (pay per product, failures free)

- **Product** (`product`): **$0.0006 per product** saved to your dataset ($0.60 per 1,000; per variation row in variation mode), $0.00054 on Silver and $0.00048 on Gold. Variation details in product mode are included.
- **Free:** sites that are not WooCommerce, blocked sites, stores whose robots.txt disallows the API, unreachable sites and filtered-out products.

Set a maximum cost per run and the Actor stops gracefully when it is reached. See the *Pricing* tab for current tier discounts.

### Limitations

- Works with WooCommerce stores whose public Store API is available (WooCommerce 6+; most stores). Some stores disable it, protect it with bot checks, or disallow it in robots.txt; these are skipped and not charged.
- Only data the store shows publicly is available. Sales numbers, cost prices and exact stock quantities (unless the store shows them) are not.
- The Store API does not expose product dates; use monitoring mode to detect new products.
- Prices are shown as the store shows them to a guest visitor (tax display and currency follow the store settings).

### Use with AI agents (MCP)

This Actor works as a tool for AI agents through the **Apify MCP server** at `https://mcp.apify.com`. Connect Claude, Cursor, VS Code, n8n or any other MCP client to `https://mcp.apify.com?tools=tinyrex/woocommerce-products-scraper` and ask, for example: *"Get all products and variation prices from nalgene.com"*. Results come back as structured JSON at the same pay-per-product price; failed inputs stay free.

📘 **Step-by-step guide with Python, JavaScript, curl and MCP examples:** [How to export products from any WooCommerce store to CSV or JSON](https://emirmrkaljevic.github.io/tinyrex-data-tools/export-woocommerce-store-products-to-csv/)

### FAQ

**How do I export all products from a WooCommerce store?** Enter the store domain and set *Max products per store* to `0`. The Actor reads the store's public Store API and gives you every product as CSV, Excel or JSON, with variations nested or as separate rows. You don't need admin access or API keys.

**Can I scrape a WooCommerce store I don't own?** Yes, for public product data. The Actor reads the Store API that WooCommerce provides for storefronts and follows each store's `robots.txt`. It does not log in and does not access customer or order data. Use the data in line with the store's terms and your local law.

**How do I track a competitor's WooCommerce prices?** Set *Monitoring mode* to *New products and price/stock changes*, schedule the Actor daily, and connect an integration (email, Slack, Google Sheets). The first run is the baseline; later runs return only new products and changes, with `previousPrice` and `previousInStock`.

**How do I know if a website runs WooCommerce?** Just add it: other sites are reported as `not_woocommerce` in the `STORES` record and are free. For a long domain list, run the [Tech Stack Detector](https://apify.com/tinyrex/tech-stack-detector) with its `onlyIfUses` filter set to `WooCommerce` first.

**How fast is it?** In our test, 24 stores with 2,637 products took about 4 minutes; most of the time is spent waiting for the stores' servers. Speed depends on store size and hosting.

**My store isn't recognized.** Check the `STORES` record for the reason. If the status is `not_woocommerce` but the store runs WooCommerce, open an issue with the URL and we will take a look.

### Related actors

- [Shopify Products Scraper](https://apify.com/tinyrex/shopify-products-scraper): The same product export for Shopify stores, including headless ones.
- [Tech Stack Detector](https://apify.com/tinyrex/tech-stack-detector): Find out which domains run WooCommerce first (`onlyIfUses: WooCommerce`), then feed them here.
- [Contact Details Extractor](https://apify.com/tinyrex/contact-details-extractor): Company emails, phones and social links for the shops you found.
- [Sitemap Scraper](https://apify.com/tinyrex/sitemap-scraper): List every URL on a store's sitemap, including product and category pages.

# Actor input Schema

## `stores` (type: `array`):

Store domains (nalgene.com), store URLs, category URLs (https://store.com/product-category/mugs/) or product URLs (https://store.com/product/blue-mug/). Uses the store's public WooCommerce Store API. Sites that are not WooCommerce, block access or disallow the API in robots.txt are skipped and not charged.

## `maxProductsPerStore` (type: `integer`):

Maximum number of products to save per input (after filters). 0 = all products. Newest products come first.

## `outputMode` (type: `string`):

Product: one row per product, variations nested. Variation: one flat row per variation (size/color) - easiest for spreadsheets and price tracking; simple products still give one row. One charge per row.

## `search` (type: `string`):

Optional. Uses the store's own product search, so only matching products are downloaded - fastest way to scan big stores for one product line.

## `keywords` (type: `array`):

Keep only products whose title, SKU, categories, tags or brands contain any of these words (case-insensitive).

## `excludeKeywords` (type: `array`):

Drop products whose title or tags contain any of these words.

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

Keep only products in these categories (name or slug, partial match). To download just one category, you can also paste its URL as input.

## `brands` (type: `array`):

Keep only products of these brands (partial match). Works on stores that use WooCommerce Brands.

## `minPrice` (type: `integer`):

Lowest price must be at least this (store currency). 0 = no limit.

## `maxPrice` (type: `integer`):

Lowest price must be at most this (store currency). 0 = no limit.

## `onlyInStock` (type: `boolean`):

Keep only products that are in stock.

## `onlyOnSale` (type: `boolean`):

Keep only discounted products.

## `minDiscountPercent` (type: `integer`):

Keep only products whose discount (regular vs sale price) is at least this percent. 0 = off. Products below the cut, and products with no discount, are free. Variable products with only a price range and no single discount % are dropped when this is set.

## `includeVariations` (type: `boolean`):

Add price, regular price, SKU and stock for every variation of variable products. Costs nothing extra (one request per 100 variations).

## `descriptionFormat` (type: `string`):

Short and full description as plain text, HTML, both, or none (smaller output).

## `monitorMode` (type: `string`):

Off: return all matching products. New: only products not seen in previous runs. Changes: new products plus price or stock changes (with previous values). State is kept per store under the state key. The first monitoring run returns everything as the baseline.

## `stateKey` (type: `string`):

Name of the monitoring state. Use different keys for different schedules or filters.

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

How many stores are processed at the same time. Pages of one store are fetched politely one after another.

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

Usually not needed. Use a proxy if a store rate-limits requests (HTTP 429).

## Actor input object example

```json
{
  "stores": [
    "https://nalgene.com",
    "mandarinstone.com"
  ],
  "maxProductsPerStore": 100,
  "outputMode": "products",
  "search": "",
  "keywords": [],
  "excludeKeywords": [],
  "categories": [],
  "brands": [],
  "minPrice": 0,
  "maxPrice": 0,
  "onlyInStock": false,
  "onlyOnSale": false,
  "minDiscountPercent": 0,
  "includeVariations": true,
  "descriptionFormat": "text",
  "monitorMode": "off",
  "stateKey": "default",
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Products with prices, variations, stock, categories and images.

## `stores` (type: `string`):

For every input: status (ok, not_woocommerce, blocked, disallowed_by_robots, not_found...), store name, currency, products found/saved, notes.

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

Totals for the run.

# 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 = {
    "stores": [
        "https://nalgene.com",
        "mandarinstone.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tinyrex/woocommerce-products-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 = { "stores": [
        "https://nalgene.com",
        "mandarinstone.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("tinyrex/woocommerce-products-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 '{
  "stores": [
    "https://nalgene.com",
    "mandarinstone.com"
  ]
}' |
apify call tinyrex/woocommerce-products-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tinyrex/woocommerce-products-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/DOrw9o0FzP8gPpxdQ/builds/YdDGnS3no0eH3KVNm/openapi.json
