# Woolworths Scraper - AU Prices, Specials & Unit Price (`haketa/woolworths-scraper`) Actor

Scrape Woolworths Australia products by keyword or category: price, was-price, savings %, half-price & member specials, online vs in-store price, unit price, availability, brand, dietary and allergens. Export to JSON, CSV, Excel.

- **URL**: https://apify.com/haketa/woolworths-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** E-commerce
- **Features:** Limited permissions
- **Stats:** 6 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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?

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

## Woolworths Scraper 🛒🇦🇺 — Australia Grocery Prices, Specials, Unit Price & In-Store Price

[![No Login Required](https://img.shields.io/badge/Login-Not%20Required-brightgreen)](#)
[![No API Key](https://img.shields.io/badge/API%20Key-Not%20Required-brightgreen)](#)
[![Export Formats](https://img.shields.io/badge/Export-JSON%20%7C%20CSV%20%7C%20Excel%20%7C%20API-blue)](#)
[![Specials Intelligence](https://img.shields.io/badge/Specials-Half--Price%20%2B%20Member%20Deals-ff69b4)](#)
[![Dual Pricing](https://img.shields.io/badge/Pricing-Online%20%2B%20In--Store%20%2B%20Unit%20Price-teal)](#)
[![Scale](https://img.shields.io/badge/Scale-1%2C000%2B%20Products%20%2F%20Run-orange)](#)

**Extract structured product, pricing, and promotion data from [Woolworths Australia](https://www.woolworths.com.au) — Australia's largest supermarket chain.** This **Woolworths scraper** lets you **scrape Woolworths** by keyword or sweep entire grocery aisles and export hundreds to thousands of products with **online price, was-price, savings amount & %, half-price & Everyday Rewards member specials, separate in-store price, unit price (`$/100g`, `$/1L`, `$/1KG`), stock availability, barcode/GTIN, brand, Health Star Rating, dietary tags, allergens, and ingredients**.

No login, no coding, no API key required. Export directly to **JSON, CSV, Excel (XLSX), XML, or REST API**.

> **🛒 Built for retail price-monitoring teams, FMCG & CPG brand managers, grocery comparison apps, deal & cashback platforms, inflation researchers, and e-commerce intelligence pipelines.**

***

### ⚡ At a Glance

| Feature | Details |
| --- | --- |
| **Target Platform** | [Woolworths.com.au](https://www.woolworths.com.au) — Australia's #1 Supermarket & Grocery Retailer |
| **Search & Discovery Modes** | Keyword Search (`searchTerms`) + Full Category / Aisle URL Sweeps (`startUrls`) + Specials-Only Filter (`specialsOnly`) |
| **Pricing Intelligence** | `price`, `wasPrice`, `savingsAmount`, `savingsPercent`, `isOnSpecial`, `isHalfPrice`, `isMemberSpecial` |
| **Dual Online vs. In-Store** | Separate `inStorePrice`, `inStoreWasPrice`, and `inStoreIsOnSpecial` alongside online pricing |
| **Unit Price Normalization** | `unitPrice`, `unitMeasure` (`1KG`, `100G`, `1L`), and formatted `unitPriceLabel` (`$17.50 / 1KG`) |
| **Product & Nutrition Data** | `stockcode`, `barcode` (GTIN), `brand`, `packageSize`, `variety`, `healthStarRating` (0.5–5), `dietary`, `allergens`, `ingredients` |
| **Pagination & Scale** | Automatic 36-item/page pagination across up to 250 pages per target + multi-query expansion — **1,000+ products per run** |
| **Deduplication** | 100% deduplicated across overlapping searches and categories via `stockcode` |

***

### 📑 Table of Contents

- [Why Scrape Woolworths Australia?](#-why-scrape-woolworths-australia)
- [What This Woolworths Scraper Does](#-what-this-woolworths-scraper-does)
- [Use Cases](#-use-cases)
- [Input Configuration](#-input-configuration)
- [Output Schema & Field Reference](#-output-schema--field-reference)
- [Pagination & 1,000+ Scale](#-pagination--1000-scale)
- [How to Use](#️-how-to-use)
- [API Usage Examples](#-api-usage-examples)
- [Tips for Best Results](#-tips-for-best-results)
- [FAQ](#-faq)
- [Related Scrapers](#-related-scrapers)
- [Changelog](#-changelog)

***

### 🔎 Why Scrape Woolworths Australia?

Woolworths is Australia's largest grocery retailer, carrying tens of thousands of SKUs across fresh produce, pantry staples, meat, dairy, bakery, household essentials, health, and personal care — with prices, half-price promotions, and Everyday Rewards member specials rotating every week (Wednesday catalog cycle).

Tracking Woolworths pricing manually is impractical:

- **No public Woolworths API:** Woolworths does not provide an open developer API for catalog exports or historical price tracking.
- **Hidden pricing layers:** A single product tile can have an **online price**, a different **in-store shelf price**, a **previous (`was`) price**, a **unit price** (`$/100g` or `$/1KG`), a **50%-off half-price badge**, or an **Everyday Rewards member deal**.
- **Rich product attributes buried in product records:** Barcodes (GTIN/EAN), Australian **Health Star Ratings**, allergen declarations, dietary lifestyle flags (*Gluten Free*, *Vegan*, *Vegetarian*, *Low Sugar*), and ingredient lists require structured extraction.

This **Woolworths data extractor** captures all of those layers in a single pass, streaming clean, deduplicated product records ready for BI dashboards, cross-retailer matching (e.g., Woolworths vs. Coles on `barcode`), and automated price-drop alerts.

***

### ✨ What This Woolworths Scraper Does

- 🔎 **Multi-Keyword Search (`searchTerms`)** — pass any list of grocery keywords (e.g., `chocolate`, `coffee`, `milk`, `olive oil`, `protein`) and paginate through all matching products automatically.
- 📂 **Full Category & Aisle Sweeps (`startUrls`)** — paste any Woolworths browse URL (such as `https://www.woolworths.com.au/shop/browse/fruit-veg` or `https://www.woolworths.com.au/shop/browse/pantry`) to extract an entire supermarket department.
- 📄 **Unlocked 1,000+ Product Pagination** — walks 36 products per page across up to 250 pages per target (`~9,000` items per category/search) and automatically expands across popular grocery categories when a large `maxItems` (`1,000+`) is requested.
- 💰 **Complete Promotional & Specials Breakdown** — captures `price`, `wasPrice`, `savingsAmount`, computed `savingsPercent`, `isOnSpecial`, `isHalfPrice`, and `isMemberSpecial` (Everyday Rewards).
- 🏬 **Dual Online + In-Store Price Comparison** — extracts `inStorePrice`, `inStoreWasPrice`, and `inStoreIsOnSpecial` so you can spot online- vs. shelf-price discrepancies.
- 📏 **Standardized Unit Pricing** — provides numeric `unitPrice`, `unitMeasure` (`100G`, `1KG`, `1L`, `1EA`), and `unitPriceLabel` (`$17.50 / 1KG`) for apples-to-apples value comparison across pack sizes.
- 🥗 **Barcodes, Health Star Rating & Nutrition Metadata** — extracts `barcode` (EAN/GTIN for exact cross-retailer matching), `brand`, `packageSize`, `unit`, `variety`, `healthStarRating` (`0.5`–`5.0`), `dietary`, `allergens`, `ingredients`, and `countryOfOrigin`.
- 🏷️ **One-Click Specials-Only Mode (`specialsOnly`)** — filter the entire run to return only discounted, half-price, and member-special items.
- 🧹 **Live Incremental Streaming & Deduplication** — pushes clean records page by page (omitting empty/null noise) and deduplicates every SKU by its unique `stockcode`.

***

### 🎯 Use Cases

| Team / Persona | How They Use This Woolworths Scraper |
| --- | --- |
| **FMCG & CPG Brand Managers** | Monitor shelf prices, promotional depth (`savingsPercent`), and out-of-stocks (`isInStock`) across your own and competitor brands. |
| **Retail Price Comparison (Woolworths vs. Coles)** | Join Woolworths products with Coles data using `barcode` (GTIN) or `unitPrice` to benchmark Australia's two supermarket giants side by side. |
| **Deal, Coupon & Cashback Platforms** | Run daily or weekly Wednesday sweeps with `specialsOnly: true` to publish live half-price (`isHalfPrice: true`) shopping guides. |
| **Grocery-Tech, Recipe & Meal-Planning Apps** | Power live basket-cost calculators, allergen-safe meal planners (`allergens`, `dietary`), and Health Star filters (`healthStarRating`). |
| **Economic & Inflation Researchers** | Track weekly food inflation, shrinkflation (`packageSize` vs. `unitPrice`), and promotional frequency across staple grocery baskets. |
| **Data & BI Engineering Teams** | Schedule automated runs into Snowflake, BigQuery, Postgres, or Google Sheets via Apify webhooks and REST API. |

***

### 📥 Input Configuration

All fields are optional. Running with empty input `{}` automatically collects a diverse multi-category grocery sample.

| Field | Key | Type | Default | Description |
| --- | --- | --- | --- | --- |
| **Search terms** | `searchTerms` | `array<string>` | `["chocolate"]` | Product keywords to search on Woolworths (`milk`, `coffee`, `chocolate`, `bread`, etc.). |
| **Woolworths URLs** | `startUrls` | `array<object>` | `[{ "url": ".../browse/fruit-veg" }]` | Woolworths `/shop/browse/...` category URLs or `/shop/search/products?searchTerm=...` URLs. |
| **Specials only** | `specialsOnly` | `boolean` | `false` | Return only products currently on special (discounted, half-price, or Everyday Rewards offers). |
| **Maximum products** | `maxItems` | `integer` | `200` (prefill `100`) | Maximum unique products to collect across all targets. Set `0` for unlimited (`1,000+` supported). |
| **Proxy configuration** | `proxyConfiguration` | `object` | `{ "useApifyProxy": true }` | Apify Proxy configuration. Default proxy is enabled and works out of the box. |

#### Example 1 — Multi-Category & Multi-Keyword Bulk Sweep (1,000+ Products)

```json
{
  "startUrls": [
    { "url": "https://www.woolworths.com.au/shop/browse/fruit-veg" },
    { "url": "https://www.woolworths.com.au/shop/browse/pantry" },
    { "url": "https://www.woolworths.com.au/shop/browse/dairy-eggs-fridge" }
  ],
  "searchTerms": ["chocolate", "coffee"],
  "specialsOnly": false,
  "maxItems": 1500
}
```

#### Example 2 — Weekly Specials & Half-Price Deal Feed

```json
{
  "searchTerms": ["chocolate", "chips", "coffee", "ice cream", "laundry"],
  "specialsOnly": true,
  "maxItems": 500
}
```

#### Example 3 — Keyword Search for Price & Unit-Price Benchmarking

```json
{
  "searchTerms": ["olive oil", "greek yogurt", "oats"],
  "startUrls": [],
  "maxItems": 300
}
```

***

### 📤 Output Schema & Field Reference

Each product is returned as a clean, flat JSON object (null/empty optional keys are stripped so records stay compact).

#### Sample Output Record

```json
{
  "stockcode": 147981,
  "name": "Woolworths White Cup Sliced Mushroom Punnet 200g",
  "brand": "Woolworths",
  "url": "https://www.woolworths.com.au/shop/productdetails/147981/woolworths-white-cup-sliced-mushroom-punnet",
  "price": 3.5,
  "wasPrice": 4,
  "savingsAmount": 0.5,
  "savingsPercent": 12,
  "isOnSpecial": true,
  "isHalfPrice": false,
  "inStorePrice": 3.5,
  "inStoreWasPrice": 4,
  "inStoreIsOnSpecial": true,
  "unitPrice": 17.5,
  "unitMeasure": "1KG",
  "unitPriceLabel": "$17.50 / 1KG",
  "packageSize": "200g",
  "unit": "Each",
  "variety": "Mushroom Punnet",
  "healthStarRating": 5,
  "isAvailable": true,
  "isInStock": true,
  "barcode": "9300633043056",
  "description": "Woolworths White Cup Sliced Mushroom Punnet 200g",
  "dietary": "Low Fat,Low Salt,Low Saturated Fat,Vegetarian",
  "category": "Fruit & Veg",
  "image": "https://cdn1.woolworths.media/content/wowproductimages/large/147981.jpg"
}
```

#### Emoji-Grouped Field Reference & Coverage

##### 🏷️ Product Identity & Catalog

| Field | Type | Coverage | Description |
| --- | --- | --- | --- |
| `stockcode` | `integer` | 🟢 High (100%) | Unique Woolworths SKU identifier (used for deduplication). |
| `name` | `string` | 🟢 High (100%) | Full product display title (`DisplayName`). |
| `brand` | `string` | 🟢 High (98%+) | Brand name (e.g., `Woolworths`, `Cadbury`, `Nescafé`). |
| `barcode` | `string` | 🟢 High (98%+) | Product GTIN / EAN-13 barcode for cross-retailer matching. |
| `url` | `string` | 🟢 High (100%) | Direct URL to the Woolworths product detail page. |
| `category` | `string` | 🟢 High (100%) | Originating category name or search query label. |
| `image` | `string` | 🟢 High (100%) | High-resolution product image URL on Woolworths CDN. |
| `packageSize` / `unit` | `string` | 🟢 High (98%+) | Pack size (e.g., `200g`, `1L`) and selling unit (`Each`, `KG`). |
| `variety` | `string` | 🟡 Conditional | Product variety or flavour when listed by Woolworths. |
| `isNew` / `isTobacco` | `boolean` | 🟡 Conditional | Present when `true` (newly ranged product or tobacco item). |

##### 💰 Online Pricing, Specials & Promotions

| Field | Type | Coverage | Description |
| --- | --- | --- | --- |
| `price` | `number` | 🟢 High (100% available) | Current online price in AUD (omitted only on seasonal/unavailable items). |
| `wasPrice` | `number` | 🟡 Conditional | Previous price in AUD when the product is discounted. |
| `savingsAmount` | `number` | 🟡 Conditional | Dollar amount saved (`wasPrice - price`) on discounted items. |
| `savingsPercent` | `integer` | 🟡 Conditional | Computed discount percentage (e.g., `50` for half-price). |
| `isOnSpecial` | `boolean` | 🟢 High (100%) | `true` when the product is currently on special. |
| `isHalfPrice` | `boolean` | 🟡 Conditional | Present (`true`) when the product is a 50%-off Half-Price special. |
| `isMemberSpecial` | `boolean` | 🟡 Conditional | Present (`true`) for Everyday Rewards member specials. |

##### 🏬 In-Store Pricing, Unit Price & Availability

| Field | Type | Coverage | Description |
| --- | --- | --- | --- |
| `inStorePrice` | `number` | 🟢 High (100% available) | In-store shelf price in AUD. |
| `inStoreWasPrice` | `number` | 🟡 Conditional | Previous in-store price when discounted in store. |
| `inStoreIsOnSpecial` | `boolean` | 🟡 Conditional | Present (`true`) when on special in physical stores. |
| `unitPrice` | `number` | 🟢 High (95%+) | Standardized cup/unit price (e.g., `17.5`). |
| `unitMeasure` | `string` | 🟢 High (95%+) | Unit measure basis (e.g., `1KG`, `100G`, `1L`, `100ML`). |
| `unitPriceLabel` | `string` | 🟢 High (95%+) | Formatted unit price string (e.g., `"$17.50 / 1KG"`). |
| `isAvailable` | `boolean` | 🟢 High (100%) | Whether the item is currently available to order. |
| `isInStock` | `boolean` | 🟢 High (90%+) | Present (`true`) when the item is in stock. |

##### 🥗 Nutrition, Dietary & Ingredients

| Field | Type | Coverage | Description |
| --- | --- | --- | --- |
| `healthStarRating` | `number` | 🟡 Conditional | Australian Health Star Rating (`0.5` to `5.0`) when listed on packaging. |
| `dietary` | `string` | 🟢 High (~85%) | Comma-separated dietary claims (*Vegetarian*, *Gluten Free*, *Vegan*, *Low Fat*). |
| `allergens` | `string` | 🟢 High (~95%) | Allergen declaration (e.g., *Contains Milk, Soy*). |
| `ingredients` | `string` | 🟢 High (~85%) | Full ingredient list with HTML stripped. |
| `countryOfOrigin` | `string` | 🟡 Conditional | Country of origin statement when provided. |
| `description` | `string` | 🟢 High (99%+) | Clean, HTML-stripped product description. |

***

### 🔁 Pagination & 1,000+ Scale

This **Woolworths scraper** is built for high-volume grocery catalog extraction:

- **36 Products per Page (Up to 250 Pages per Target):** Each search term or category browse URL paginates in increments of 36 products (`PageNumber` / `pageNumber`) up to 250 pages (~9,000 products per target) until `maxItems` is reached or the catalog ends.
- **Automatic Multi-Term Expansion for 1,000+ Runs:** If you request `maxItems: 1000+` with a single narrow keyword (or empty input `{}`), the scraper automatically appends popular grocery categories (`chocolate`, `coffee`, `milk`, `bread`, `cheese`, `chicken`, `chips`, `tea`, `pasta`, `yogurt`, `cereal`, `biscuits`, `fruit`, `vegetables`, etc.) so your run smoothly scales past 1,000+ unique products.
- **Live Page-by-Page Dataset Streaming:** Products are pushed to the Apify Dataset after every page and deduplicated across all targets by `stockcode`.

***

### ⚙️ How to Use

1. Open **Woolworths Scraper** on the **Apify Console**.
2. Enter one or more **Search terms** (`searchTerms`) and/or paste **Woolworths URLs** (`startUrls`, e.g., `https://www.woolworths.com.au/shop/browse/fruit-veg`).
3. *(Optional)* Toggle **Specials only (`specialsOnly`)** to collect only discounted products.
4. Set **Maximum products (`maxItems`)** — e.g., `100` for a quick test, `1000`+ for bulk catalog runs, or `0` for unlimited — and click **Start**.
5. Export your dataset in **JSON, CSV, Excel (XLSX), HTML, or XML**, or consume it via the **Apify API**.

***

### 💻 API Usage Examples

#### Python (`apify-client`)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("haketa/woolworths-scraper").call(run_input={
    "startUrls": [{"url": "https://www.woolworths.com.au/shop/browse/pantry"}],
    "searchTerms": ["coffee", "chocolate"],
    "specialsOnly": False,
    "maxItems": 1000,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["stockcode"], item["name"], item.get("price"), item.get("unitPriceLabel"))
```

#### Node.js (`apify-client`)

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const run = await client.actor('haketa/woolworths-scraper').call({
    searchTerms: ['milk', 'cheese', 'yogurt'],
    specialsOnly: true,
    maxItems: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Extracted ${items.length} Woolworths products on special`);
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/haketa~woolworths-scraper/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchTerms": ["coffee"],
    "specialsOnly": true,
    "maxItems": 200
  }'
```

***

### 🧭 Supported Woolworths Category Browse URLs

You can pass any Woolworths department or sub-aisle URL in `startUrls` for a complete category sweep:

| Department | Example `startUrls` Browse URL |
| --- | --- |
| **Fruit & Veg** | `https://www.woolworths.com.au/shop/browse/fruit-veg` |
| **Pantry** | `https://www.woolworths.com.au/shop/browse/pantry` |
| **Meat, Seafood & Deli** | `https://www.woolworths.com.au/shop/browse/meat-seafood-deli` |
| **Dairy, Eggs & Fridge** | `https://www.woolworths.com.au/shop/browse/dairy-eggs-fridge` |
| **Bakery** | `https://www.woolworths.com.au/shop/browse/bakery` |
| **Freezer** | `https://www.woolworths.com.au/shop/browse/freezer` |
| **Drinks** | `https://www.woolworths.com.au/shop/browse/drinks` |
| **Snacks & Confectionery** | `https://www.woolworths.com.au/shop/browse/snacks-confectionery` |
| **Health & Wellness** | `https://www.woolworths.com.au/shop/browse/health-wellness` |
| **Beauty & Personal Care** | `https://www.woolworths.com.au/shop/browse/beauty-personal-care` |
| **Baby** | `https://www.woolworths.com.au/shop/browse/baby` |
| **Pet** | `https://www.woolworths.com.au/shop/browse/pet` |
| **Household** | `https://www.woolworths.com.au/shop/browse/household` |

***

### 🔌 Integrations & Data Pipelines

- **Google Sheets & Excel:** Export directly to `.xlsx` or `.csv`, or sync weekly catalog runs into Google Sheets for live price-comparison pivot tables.
- **Data Warehouses (BigQuery, Snowflake, Postgres):** Stream runs via Apify webhooks and upsert on `(stockcode, scraped_date)` to build a longitudinal Australian supermarket inflation index.
- **Slack, Discord & Email Alerts:** Trigger Make, Zapier, or n8n workflows when `isHalfPrice == true` or `savingsPercent >= 40` on watched SKUs.

***

### 💡 Tips for Best Results

- **Schedule Wednesday runs for weekly specials:** Woolworths refreshes its weekly catalog every Wednesday; schedule a weekly Wednesday morning run with `specialsOnly: true` to capture every new half-price deal.
- **Combine `startUrls` and `searchTerms`:** Browse URLs (`/shop/browse/fruit-veg`, `/shop/browse/meat-seafood-deli`, `/shop/browse/bakery`) sweep entire aisles, while `searchTerms` target specific brands or ingredients.
- **Match across retailers via `barcode`:** Almost every packaged Woolworths SKU includes its 13-digit GTIN/EAN in `barcode`, making it effortless to join against Coles or other supermarket datasets.
- **Check `isAvailable` when analyzing missing prices:** Out-of-season or temporarily unavailable items legitimately carry no `price` on Woolworths; filter on `isAvailable: true` for active price averages.

***

### ❓ FAQ

#### Do I need a Woolworths account or API key?

No. The actor extracts public catalog and pricing data without requiring any login or API key.

#### How many products can I scrape in a single run?

You can collect **1,000 to 10,000+ unique products** in a single run. Set `maxItems: 1000` (or `0` for unlimited) and provide category browse URLs or multiple search terms.

#### Does it extract both online and in-store prices?

Yes. Every available product includes `price` (online) and `inStorePrice` (physical store), along with separate `wasPrice` / `inStoreWasPrice` and special indicators.

#### Why do a few products have no `price` field?

Temporarily unavailable items (`isAvailable: false`, such as out-of-season fruit & veg) have no active price on Woolworths. Every available item (`isAvailable: true`) has 100% price coverage.

#### Are duplicate products filtered out?

Yes. Products are deduplicated across all search terms and category URLs using Woolworths' unique `stockcode`.

***

### 🔗 Related Scrapers

Build complete retail, grocery, and e-commerce price intelligence pipelines with our companion actors:

- [Coles Scraper — AU Prices, Specials & Unit Price](https://apify.com/haketa/coles-scraper) — Benchmark Woolworths against Coles, Australia's second-largest supermarket chain.
- [Blinkit Scraper — Grocery & Quick-Commerce Prices](https://apify.com/haketa/blinkit-scraper) — Extract quick-commerce grocery prices, discounts, and inventory.
- [Flipkart Scraper](https://apify.com/haketa/flipkart-scraper) — Extract e-commerce product catalogs, ratings, and pricing.
- [Myntra Scraper](https://apify.com/haketa/myntra-scraper) — Scrape product prices, discounts, brands, and sizes.

***

### 📋 Changelog

#### v1.2.0 (2026-11)

- **Unlocked 1,000+ Deep Pagination & Multi-Query Scaling:** Raised the per-target pagination ceiling to **250 pages** (`~9,000` products per category/search), added `maxItems: 0` (unlimited) support, and implemented automatic multi-category fallback expansion so `maxItems: 1000+` runs and empty `{}` runs always scale cleanly.
- **Live Page-by-Page Dataset Streaming:** Updated dataset writes to stream each page batch incrementally rather than buffering until the end of the run.
- **Fast Prefill Execution:** Tuned prefill `maxItems` to `100` for rapid `<15s` verification runs.
- **Documentation Upgrade:** Added `⚡ At a Glance` summary table, emoji-grouped field tables with coverage indicators, and updated API examples.

#### v1.1.0 (2026-11)

- **Scale & Quality Verification:** Verified 500 unique products across category sweeps and keyword searches in ~42s with 0 duplicates and 100% coverage on core fields (`stockcode`, `name`, `url`, and `price` on available items).
- **Specials & Dual-Pricing Validation:** Confirmed accuracy of `savingsPercent`, `isHalfPrice`, `isMemberSpecial`, and `inStorePrice`.

#### v1.0.0 (2026-08)

- Initial release of Woolworths Australia Scraper supporting keyword search, category browse URLs, specials-only filtering, dual online/in-store pricing, unit pricing, barcodes, dietary/allergen metadata, and Health Star Ratings.

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/woolworths-scraper/changelog.md

# Actor input Schema

## `searchTerms` (type: `array`):

One or more product keywords to search on Woolworths (e.g. milk, coffee, chocolate). The scraper paginates through all results automatically.

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

Paste Woolworths search or category URLs — e.g. https://www.woolworths.com.au/shop/search/products?searchTerm=coffee or https://www.woolworths.com.au/shop/browse/fruit-veg. Use these for full category sweeps or pre-filtered searches.

## `specialsOnly` (type: `boolean`):

Return only products currently on special (discounted, half-price or member offers). Great for deal and price-drop tracking.

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

Maximum number of products to collect across all search terms and URLs. Set 0 for unlimited (1,000+ supported).

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

Proxy settings. Apify Proxy is enabled by default and works well; for very large or long-running jobs, Australian residential proxies can improve reliability.

## Actor input object example

```json
{
  "searchTerms": [
    "chocolate"
  ],
  "startUrls": [
    {
      "url": "https://www.woolworths.com.au/shop/browse/fruit-veg"
    }
  ],
  "specialsOnly": false,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `stockcode` (type: `string`):

Woolworths product stockcode

## `name` (type: `string`):

Product name

## `brand` (type: `string`):

Brand

## `url` (type: `string`):

Product page URL

## `price` (type: `string`):

Current online price

## `wasPrice` (type: `string`):

Previous price (when on special)

## `savingsPercent` (type: `string`):

Discount percentage

## `isOnSpecial` (type: `string`):

Whether currently on special

## `inStorePrice` (type: `string`):

In-store price

## `unitPriceLabel` (type: `string`):

Price per unit (e.g. $2.35 / 1L)

## `packageSize` (type: `string`):

Package size

## `variety` (type: `string`):

Product variety / flavour (e.g. Sour Cream & Onion, Merlot)

## `healthStarRating` (type: `string`):

Australian Health Star Rating 0.5-5 (when available)

## `isAvailable` (type: `string`):

Availability

## `image` (type: `string`):

Product image URL

# 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 = {
    "searchTerms": [
        "chocolate"
    ],
    "startUrls": [
        {
            "url": "https://www.woolworths.com.au/shop/browse/fruit-veg"
        }
    ],
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/woolworths-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 = {
    "searchTerms": ["chocolate"],
    "startUrls": [{ "url": "https://www.woolworths.com.au/shop/browse/fruit-veg" }],
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/woolworths-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 '{
  "searchTerms": [
    "chocolate"
  ],
  "startUrls": [
    {
      "url": "https://www.woolworths.com.au/shop/browse/fruit-veg"
    }
  ],
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/woolworths-scraper --silent --output-dataset

```

## MCP server setup

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