# WooCommerce Scraper — Products, Prices, SKU, Stock & Images (`haketa/woocommerce-scraper`) Actor

Scrape products from any WooCommerce store: name, SKU, price, sale & regular price, currency, images, categories, tags, brands, attributes, variations, stock status, rating & full description. Point it at store URLs, filter by search or category. Export JSON/CSV/Excel.

- **URL**: https://apify.com/haketa/woocommerce-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** 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 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## WooCommerce Scraper — Products, Prices, SKU, Stock & Images

Extract the full product catalog from **any WooCommerce store**. Paste one or more store URLs and get every product back as clean, structured data — name, SKU, price, sale and regular price, currency, images, categories, tags, brands, attributes, variations, stock status, rating and full description.

Built for **price‑monitoring and repricing teams, dropshippers, marketplace sellers, product researchers and competitive‑intelligence analysts** who need WooCommerce catalog data as JSON, CSV or Excel instead of copying it by hand.

***

### ✨ Why use this scraper

- **Works on any WooCommerce store.** WooCommerce powers millions of independent shops — point this at any of them and it pulls the catalog, no per‑store setup.
- **Complete product records.** Price, sale price, regular price, currency, SKU, stock, categories, tags, brands, attributes, variations, rating and description — all in one row per product.
- **Clean, normalized prices.** Prices come back as proper decimal numbers in the store's currency, ready for math — no scraping price strings out of HTML.
- **Whole catalog or filtered.** Grab an entire store, or narrow it down by search term, category or on‑sale status.
- **Multiple stores at once.** Paste a list of stores and collect them all in a single run.
- **Fast and reliable.** It reads the store's own product data, so extraction is quick and consistent across stores.
- **Export anywhere.** JSON, CSV, Excel, HTML or via the Apify API and integrations.

***

### 🚀 Quick start

1. Paste one or more **WooCommerce store URLs** (the homepage is enough).
2. *(Optional)* Add a **search term** or **category**, or tick **On sale only**.
3. Set the limits and click **Start**.

Each product in the store(s) becomes one clean record.

***

### 📥 Input

| Field | Type | Description |
|---|---|---|
| **Store URLs** (`storeUrls`) | array | WooCommerce store URLs. Each store's products are collected. |
| **Search term** (`searchTerm`) | string | Optional keyword to filter products within each store. |
| **Category** (`category`) | string | Optional category slug or numeric ID to filter products. |
| **On sale only** (`onSaleOnly`) | boolean | Only return products currently on sale. |
| **Max products per store** (`maxProductsPerStore`) | integer | Cap per store. |
| **Maximum products (total)** (`maxItems`) | integer | Overall cap across all stores. |
| **Concurrency** (`maxConcurrency`) | integer | How many stores to process in parallel. |
| **Proxy configuration** (`proxyConfiguration`) | object | Apify Proxy is recommended for reliable access. |

#### Example 1 — a whole store

```json
{
  "storeUrls": [{ "url": "https://barefootbuttons.com" }]
}
```

#### Example 2 — several stores, capped

```json
{
  "storeUrls": [
    { "url": "https://store-one.com" },
    { "url": "https://store-two.com" }
  ],
  "maxProductsPerStore": 500
}
```

#### Example 3 — filter by search and sale

```json
{
  "storeUrls": [{ "url": "https://example-store.com" }],
  "searchTerm": "cable",
  "onSaleOnly": true
}
```

#### Example 4 — a single category

```json
{
  "storeUrls": [{ "url": "https://example-store.com" }],
  "category": "accessories"
}
```

***

### 📤 Output

Each product is one dataset item. Example:

```json
{
  "storeUrl": "https://barefootbuttons.com",
  "productId": 1475,
  "name": "Replacement Set Screw and Allen Wrench Kit",
  "slug": "replacement-set-screw-and-allen-wrench-kit",
  "sku": "18-AC-AS-02",
  "type": "variable",
  "permalink": "https://barefootbuttons.com/product/replacement-set-screw-and-allen-wrench-kit/",
  "price": 1.95,
  "regularPrice": 1.95,
  "salePrice": null,
  "priceMin": null,
  "priceMax": null,
  "onSale": false,
  "currency": "USD",
  "shortDescription": "Genuine replacement hardware for Barefoot Buttons.",
  "description": "Every Barefoot Button includes the hardware needed for installation...",
  "categories": ["Accessories"],
  "tags": [],
  "brands": [],
  "averageRating": 0,
  "reviewCount": 0,
  "inStock": true,
  "purchasable": true,
  "onBackorder": false,
  "lowStockRemaining": null,
  "stockAvailability": "In stock",
  "attributes": [{ "name": "Set Screw Size", "options": ["M3", "M4"] }],
  "variationsCount": 2,
  "hasOptions": true,
  "weight": "0.1 kg",
  "dimensions": "5 × 5 × 1 cm",
  "mainImage": "https://barefootbuttons.com/wp-content/uploads/2026/06/set-screws.png",
  "images": ["https://barefootbuttons.com/wp-content/uploads/2026/06/set-screws.png"],
  "imageCount": 1,
  "scrapedAt": "2026-08-25T10:00:00.000Z"
}
```

#### Field reference

**Identity**

| Field | Description |
|---|---|
| `storeUrl` | The store the product came from. |
| `productId` | WooCommerce product ID. |
| `name` | Product name. |
| `slug` | URL slug. |
| `sku` | Stock keeping unit, when set. |
| `type` | `simple`, `variable`, `grouped`, etc. |
| `permalink` | Product page URL. |

**Pricing**

| Field | Description |
|---|---|
| `price` | Current price (decimal, in `currency`). |
| `regularPrice` | Regular (non‑sale) price. |
| `salePrice` | Sale price when on sale. |
| `priceMin`, `priceMax` | Price range for variable products. |
| `onSale` | Whether the product is on sale. |
| `currency` | Currency code (e.g. USD, EUR, GBP). |

**Content & taxonomy**

| Field | Description |
|---|---|
| `shortDescription`, `description` | Product descriptions (clean text). |
| `categories`, `tags`, `brands` | Category, tag and brand names. |
| `attributes` | Product attributes and their options. |
| `variationsCount`, `hasOptions` | Number of variations and whether it has options. |

**Stock & ratings**

| Field | Description |
|---|---|
| `inStock`, `purchasable`, `onBackorder` | Availability flags. |
| `lowStockRemaining`, `stockAvailability` | Stock hints. |
| `averageRating`, `reviewCount` | Rating and number of reviews. |

**Media & meta**

| Field | Description |
|---|---|
| `mainImage`, `images`, `imageCount` | Main image and full image list. |
| `weight`, `dimensions` | Shipping weight and dimensions. |
| `scrapedAt` | ISO timestamp of the scrape. |

***

### 💡 Use cases

- **Price monitoring & repricing** — track competitors' prices, sale prices and stock across many WooCommerce stores, and keep your own pricing sharp.
- **Dropshipping** — pull supplier catalogs with SKUs, prices, images and stock to import into your own store.
- **Competitive intelligence** — see what products, categories and price points competitors carry, and how their catalog changes over time.
- **Product & market research** — analyze assortments, price distributions and ratings across a segment.
- **Catalog migration & backup** — export a full product catalog to move platforms or keep a structured snapshot.
- **MAP & availability monitoring** — watch for minimum‑advertised‑price violations and out‑of‑stock items.
- **Feed building** — assemble product feeds for marketplaces, comparison sites and ads.

***

### 🧠 How it works

The scraper reads each store's **public product data** and paginates through the whole catalog, so you don't have to click through category and product pages one by one. Prices are returned as clean decimal numbers in the store's currency, images and taxonomy come through structured, and everything is normalized into the same schema regardless of which store it came from — so a run across ten different shops still gives you one consistent dataset.

Because it works at the catalog level, a single store URL is enough to pull the entire product range; filters let you narrow to a search term, a category, or only on‑sale items when you don't need everything.

***

### 🎯 Tips for best results

- **The homepage URL is enough.** You don't need to find a special page — paste the store's main URL and the scraper handles the rest.
- **Cap large catalogs.** For very large stores, set `maxProductsPerStore` to keep runs quick while you test, then raise it.
- **Filter to focus.** Use `searchTerm` or `category` to pull just the part of the catalog you care about.
- **Watch prices over time.** Schedule the run to build a price and stock history for repricing and MAP checks.
- **Combine stores.** Paste a list of competitor stores to benchmark an entire segment in one run.

***

### 📈 Scaling up

- Paste **many store URLs** and raise concurrency to cover a whole segment in one run.
- Raise **Max products per store** to pull full catalogs; lower it to sample quickly.
- **Schedule** recurring runs to keep a fresh price, stock and catalog feed.

***

### 🧾 Prices, sales & variations explained

- **Regular vs. sale vs. current.** `regularPrice` is the list price, `salePrice` is the discounted price when the product is on sale, and `price` is what a shopper pays right now. Compare `regularPrice` and `price` to compute the discount.
- **Variable products.** A product with options (size, colour, …) has `type: "variable"`, a `variationsCount`, and its `attributes` list the available options. Its `priceMin`/`priceMax` give the range across variations.
- **On‑sale filter.** Set **On sale only** to return just the discounted products — handy for deal monitoring and MAP checks.
- **Currency‑aware.** Every price carries the store's `currency`, so a multi‑store run stays correct even when shops use different currencies.
- **Stock at a glance.** `inStock`, `onBackorder`, `stockAvailability` and `lowStockRemaining` tell you what's actually buyable.

***

### 🧩 What you can build with the data

- **A price‑and‑stock monitor** — schedule the run across competitor stores and alert on price drops, new sales or out‑of‑stock items.
- **A repricing feed** — pull competitor `price`/`regularPrice`/`onSale` and drive your own pricing rules.
- **A dropshipping importer** — map `name`, `sku`, `price`, `images`, `categories` and `description` straight into your own store.
- **A market map** — aggregate `categories`, price bands and ratings across a segment to spot gaps and opportunities.
- **A MAP‑compliance checker** — flag products priced below your minimum advertised price across many resellers.
- **A catalog snapshot** — keep dated exports to track how a store's assortment and prices evolve.

***

### 🔌 Run it your way

- **Apify Console** — paste store URLs and click Start.
- **API** — start runs and pull the dataset programmatically.
- **Scheduler** — refresh prices and stock on a schedule.
- **Integrations** — push results to Google Sheets, Zapier, Make, webhooks, S3 and more.

***

### ❓ FAQ

**Does it work on any WooCommerce store?**
It works on the large majority of WooCommerce stores that expose their standard public product data. A few stores lock this down; those come back with a clear note that the product data wasn't available.

**Do I need an API key or login?**
No. Just paste the store URL.

**Are prices accurate and in the right currency?**
Yes — prices are returned as decimal numbers together with the store's `currency` code, exactly as the store publishes them.

**Can I get only sale items, or one category?**
Yes. Use **On sale only**, or set a **Category** slug/ID, or a **Search term** to filter.

**Do I get product variations?**
Each product includes its `attributes`, `variationsCount` and, for variable products, a `priceMin`/`priceMax` range.

**How many products can I collect?**
Whole catalogs — set `maxProductsPerStore` and `maxItems` to control the totals.

**In what format is the data?**
Structured JSON by default, exportable to CSV, Excel, HTML and more.

**Can I run it on a schedule?**
Yes — use the Apify Scheduler, or start runs through the Apify API and its integrations.

**Can I scrape several stores at once?**
Yes — paste a list of store URLs. Each product carries its `storeUrl`, so you can compare across shops in one dataset.

**Why do some products have no SKU or attributes?**
Not every store fills in a SKU, and simple products often have no attributes — those fields come back empty for those products, which is normal.

**Does it handle different currencies?**
Yes. Prices are decimal numbers and each product includes its store's `currency` code, so multi‑store, multi‑currency runs stay accurate.

**What if a store is very large?**
Set `maxProductsPerStore` to sample or to cap big catalogs, and `maxItems` for the overall total. The scraper paginates the whole catalog otherwise.

**What if a store blocks the product data?**
A small number of stores restrict access; those are reported clearly and skipped, so the rest of your run still completes.

***

### ⚖️ Legal & responsible use

This tool collects **publicly available** product information for legitimate business use such as price monitoring, market research and competitive analysis. You are responsible for how you use the data and for complying with all applicable laws and regulations, each store's terms, and data‑protection rules (including GDPR/CCPA where relevant). Do not use the output to infringe intellectual‑property rights or for any unlawful purpose. This scraper is not affiliated with WooCommerce, Automattic, or the stores whose catalogs you choose to process; all trademarks belong to their respective owners.

***

#### Tags

`woocommerce` · `woocommerce scraper` · `ecommerce scraper` · `product scraper` · `price monitoring` · `price tracker` · `dropshipping` · `product data` · `catalog scraper` · `wordpress` · `stock monitoring` · `competitor prices` · `sku` · `product feed` · `repricing`

# Actor input Schema

## `storeUrls` (type: `array`):

WooCommerce store URLs (the homepage or any page of the store). Each store's products are collected. Example: https://barefootbuttons.com

## `searchTerm` (type: `string`):

Optional keyword to filter products within each store (matches product name and description).

## `category` (type: `string`):

Optional category slug (e.g. accessories) or numeric category ID to filter products.

## `onSaleOnly` (type: `boolean`):

Only return products that are currently on sale.

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

Maximum number of products to collect from each store.

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

Overall cap on the number of product records saved across all stores.

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

How many stores to process in parallel. Recommended 3–6.

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

Apify Proxy is recommended for reliable access.

## Actor input object example

```json
{
  "storeUrls": [
    {
      "url": "https://woocommerce.com"
    }
  ],
  "searchTerm": "cable",
  "category": "accessories",
  "onSaleOnly": false,
  "maxProductsPerStore": 20,
  "maxItems": 10000,
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "storeUrls": [
        {
            "url": "https://woocommerce.com"
        }
    ],
    "maxProductsPerStore": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/woocommerce-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 = {
    "storeUrls": [{ "url": "https://woocommerce.com" }],
    "maxProductsPerStore": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/woocommerce-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 '{
  "storeUrls": [
    {
      "url": "https://woocommerce.com"
    }
  ],
  "maxProductsPerStore": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/woocommerce-scraper --silent --output-dataset

```

## MCP server setup

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