# Woolworths, Aldi & IGA Scraper: Australian Grocery Prices (`alduinxx/woolworths-aldi-scraper`) Actor

Woolworths, Aldi and IGA (store by store) grocery prices in one run: shelf and was price, half-price and multibuy specials, member prices, Super Savers, unit prices, barcodes and stock. Search by product name, give category or product URLs, read whole catalogues, or get specials only.

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

## Pricing

from $0.75 / 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.

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

Prices, specials and unit prices from **Woolworths**, **Aldi** and **IGA** in Australia in one run: the shelf price, the was price, half-price and multibuy deals, Woolworths member prices, Aldi Super Savers, IGA specials with the day they end, the unit price, barcodes and stock. IGA prices are read **store by store**, from any of the 500+ IGA stores on IGA Shop.

### Why this one

| | This Actor |
|---|---|
| Woolworths, Aldi and IGA in one run, with the same fields for all three | ✅ |
| IGA prices for the stores you choose, by postcode, suburb or store number (every IGA sets its own prices) | ✅ `storeId`, `storeName` |
| Price, was price, saving, and the deal: half price, multibuy (e.g. 2 for $7), member price, Super Savers, IGA specials | ✅ `price`, `wasPrice`, `saveAmount`, `promoType`, `promoText`, `multibuyQuantity`, `multibuyPrice` |
| When an IGA special ends | ✅ `specialEnds` |
| Unit price for comparing pack sizes | ✅ `unitPrice`, `unitMeasure`, `unitPriceText` |
| Barcodes for matching products with other sources | ✅ every Woolworths row |
| Search terms, category pages, product pages, whole catalogues, or specials only | ✅ |

### What you get

One row per product (per product and store for IGA). Three real rows (1–4 Nov 2026):

| Field | Woolworths | Aldi | IGA |
|---|---|---|---|
| `chain` | Woolworths | Aldi | IGA |
| `storeId`, `storeName` | empty | empty | 32600 · Ashcroft's IGA Erskine Park |
| `productId` | 620882 | 284934 | 856781 |
| `name`, `brand`, `size` | Chris' Traditional French Onion Dip · Chris' · 200g | Goat's Cheese Barrel Spreadable 150g · EMPORIUM SELECTION · 150 g | Bulla Double Cream · Bulla · 200mL |
| `price`, `wasPrice`, `saveAmount` | 4.5 · empty · empty | 3.99 · empty · empty | 4 · 4.95 · 0.95 |
| `onSpecial`, `promoType`, `promoText` | true · MULTIBUY · 2 for $7.00 | false · LOWER_PRICE · empty | true · SAVE · Save $0.95 |
| `specialEnds` | empty | empty | 2026-11-10 |
| `multibuyQuantity`, `multibuyPrice` | 2 · 7 | empty | empty |
| `unitPrice`, `unitMeasure`, `unitPriceText` | 2.25 · 100g · $2.25 / 100G | 26.6 · 1kg · $26.60 per 1 kg | 2 · 100mL · $2.00/100ml |
| `inStock` | true | empty (Aldi doesn't sell groceries online) | true |
| `barcode` | 9312726000150 | empty | empty |
| `category`, `categoryPath` | Dips · Dairy, Eggs & Fridge > Dips & Pate > Dips | Cheese · Dairy, Eggs & Fridge > Cheese | Cream and Cooking Creams · Dairy, Eggs and Fridge > Milk and Cream > Cream and Cooking Creams |
| `url`, `imageUrl` | the product page and its image | the product page and its image | the product page and its image |
| `searchTerm` | the search term that found the product | | |
| `scrapedAt` | ISO timestamp | ISO timestamp | ISO timestamp |

Every row has every key; values a supermarket doesn't publish come back empty rather than missing.

### What people use it for

- **Price comparison** between Woolworths, Aldi and IGA, by product or by unit price
- **Local price checks**: the same products at several IGA stores, which each set their own prices
- **Specials tracking**: every half-price, multibuy and price cut each week
- **Price monitoring** for brands and suppliers: shelf price, deals and stock over time
- **Basket and inflation studies** built on the same products week after week

### How to use it

1. Choose the **Supermarkets**. For IGA, add **IGA stores**: postcodes, suburbs or store numbers (empty means the IGA Shop's default store, Ashcroft's IGA Erskine Park, NSW 2759).
2. Add **Search terms** (e.g. `milk`, `peanut butter`, `nappies`), **Category URLs** or **Product URLs**. Leave them all empty to read the whole catalogues.
3. Tick **Specials only** to get only products on special.
4. Set **Maximum results** and run it.

#### Input examples

```json
{
    "chains": ["Woolworths", "Aldi"],
    "searchTerms": ["peanut butter", "nappies"],
    "maxResults": 300
}
```

```json
{
    "chains": ["Woolworths"],
    "specialsOnly": true,
    "maxResults": 5000
}
```

```json
{
    "chains": ["IGA"],
    "igaStores": ["2000", "Erskine Park NSW", "4670"],
    "searchTerms": ["full cream milk"],
    "maxResults": 150
}
```

```json
{
    "categoryUrls": [
        "https://www.woolworths.com.au/shop/browse/dairy-eggs-fridge/cheese",
        "https://www.aldi.com.au/products/dairy-eggs-fridge/k/960000000",
        "https://www.igashop.com.au/categories/dairy-eggs-and-fridge/cheese"
    ],
    "maxResults": 1000
}
```

### Notes

- **Search terms** are matched against each supermarket's full product list (Woolworths' published product list, Aldi's catalogue) or, for IGA, the first few thousand results of IGA Shop's own search: every word of the term must be in the product's name. Woolworths and Aldi rows come closest names first, so `milk` gives plain milks before milk chocolate; IGA rows keep IGA Shop's own order. Pack sizes don't count against a match, and among equally close Woolworths names its own brand comes first. A brand works as a search term too.
- **Results per search term** caps the rows each term gets at each supermarket (and each IGA store). `1` gives the closest match for every term, one row per term per supermarket: a quick way to price a shopping list at all three.
- **Specials only** keeps price cuts (`SAVE`), `HALF_PRICE`, `MULTIBUY`, Woolworths `MEMBER_PRICE`, Aldi `SUPER_SAVER` and IGA specials. With no search terms or URLs it reads each Woolworths department's specials, Aldi's catalogue and each IGA store's specials list. Standing prices are marked but aren't specials: Woolworths `LOWER_SHELF_PRICE`, and Aldi `LOWER_PRICE` and `LIMITED_TIME`.
- **Which prices.** Woolworths shows its online prices, the same across Australia for most products; Aldi's prices are the same in every store. Every IGA is independently owned and sets its own prices, so IGA rows are per store (`storeId`, `storeName`) and each chosen store counts as one supermarket for **Maximum results**.
- **IGA stores.** A postcode picks the store there (the run's log names the others at the same postcode), or the store at the nearest postcode when there is none. A suburb can have a state after it (`Hamilton Hill WA`). Store numbers are in the run's log and in every IGA row. IGA's `specialEnds` is the last day of the special price.
- **Stock.** Woolworths and IGA give in stock or not (`inStock`). Aldi Australia doesn't sell groceries online, so its rows have no stock.
- **Products sold by weight** at IGA: `size` is `per kg` when the price is per kilogram, and ends in `avg` (e.g. `250g avg`) when the price is for an item of average weight.
- **Products with no price** (Woolworths lists some it can't sell online right now) are skipped and not charged.
- **Maximum results** is shared evenly between the supermarkets; one that runs out passes its share on.
- **Coles** isn't included: its site refuses automated access.
- **Catalogue sizes (1–4 Nov 2026):** Woolworths' product list has about 40,000 products (many not sold online at any one time); Aldi's catalogue about 3,300; IGA Shop's default store lists about 13,800, and each IGA store's range is its own.
- **Speed** (1–4 Nov 2026): 2,000 rows from the Woolworths and Aldi catalogues in about a minute, and from one IGA store's in about 15 seconds; a search term in all three in about a minute and a half (IGA alone: two terms at two stores in 14 seconds).

### Pricing

**$0.75 per 1,000 rows** (one row per product), and nothing else to work out: platform usage, including the proxies, is included. Each run also has a start fee of $0.005.

**Maximum results** caps what a run costs: 100 rows cost $0.075, and 10,000 rows $7.50. If you set a maximum cost per run, the Actor stops when it is reached and keeps the rows found so far.

### Related Actors

- [Sobeys Grocery Scraper](https://apify.com/alduinxx/sobeys-grocery-scraper)
- [Metro Grocery Scraper](https://apify.com/alduinxx/metro-grocery-scraper)
- [Stop & Shop, Food Lion, Giant & Hannaford Grocery Scraper](https://apify.com/alduinxx/stop-shop-food-lion-giant-hannaford-scraper)
- [Canadian Tire, Sport Chek & Mark's Scraper](https://apify.com/alduinxx/canadian-tire-sport-chek-marks-scraper)

### Feedback

Found a row that looks wrong, or need a field that is missing? Open an issue on the **Issues** tab with the product URL, and it will be looked at.

# Actor input Schema

## `chains` (type: `array`):

Which supermarkets to read. Search terms and the whole-catalogue mode apply to these; category and product URLs are read from their own site whatever is chosen here.

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

Words to find in product names, e.g. "milk", "peanut butter", "nappies". Every word must appear; closest names come first. Leave empty, with no categories or products, to read each whole catalogue.

## `resultsPerTerm` (type: `integer`):

The most rows for each search term at each supermarket (and each IGA store), closest first. 1 gives the best match for every term: use it to price a shopping list at all three. Empty or 0: no limit.

## `categoryUrls` (type: `array`):

Category pages, e.g. https://www.woolworths.com.au/shop/browse/fruit-veg, https://www.aldi.com.au/products/pantry/k/970000000 or https://www.igashop.com.au/categories/dairy-eggs-and-fridge/milk-and-cream. Woolworths' specials pages (…/shop/browse/specials/half-price) work too.

## `productUrls` (type: `array`):

Product pages from any of the three sites, e.g. https://www.woolworths.com.au/shop/productdetails/888140/woolworths-full-cream-milk or https://www.igashop.com.au/product/a2-milk-full-cream-milk-726347. IGA products are read at each chosen IGA store.

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

Only products on special: price cuts, half price, multibuys, Woolworths member prices, Aldi Super Savers, IGA specials. With no search terms or URLs, this reads each Woolworths department's specials, Aldi's catalogue and each IGA store's specials list.

## `igaStores` (type: `array`):

Which IGA stores to read: every IGA is independently owned and sets its own prices. Give a postcode (the store there, or the nearest one), a suburb ("Erskine Park NSW") or a store number. Empty: the IGA Shop's default store, Ashcroft's IGA Erskine Park (NSW 2759). Up to 20 stores; each counts as one supermarket below.

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

Rows to return in total, one per product (per store for IGA). Shared evenly between the supermarkets; one that runs out passes its share on.

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

Requests at the same time. The default suits most runs.

## Actor input object example

```json
{
  "chains": [
    "Woolworths",
    "Aldi",
    "IGA"
  ],
  "searchTerms": [
    "milk"
  ],
  "categoryUrls": [],
  "productUrls": [],
  "specialsOnly": false,
  "igaStores": [],
  "maxResults": 30,
  "maxConcurrency": 10
}
```

# Actor output Schema

## `rows` (type: `string`):

No description

## `rowsCsv` (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 = {
    "chains": [
        "Woolworths",
        "Aldi",
        "IGA"
    ],
    "searchTerms": [
        "milk"
    ],
    "igaStores": [],
    "maxResults": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("alduinxx/woolworths-aldi-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 = {
    "chains": [
        "Woolworths",
        "Aldi",
        "IGA",
    ],
    "searchTerms": ["milk"],
    "igaStores": [],
    "maxResults": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("alduinxx/woolworths-aldi-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 '{
  "chains": [
    "Woolworths",
    "Aldi",
    "IGA"
  ],
  "searchTerms": [
    "milk"
  ],
  "igaStores": [],
  "maxResults": 30
}' |
apify call alduinxx/woolworths-aldi-scraper --silent --output-dataset

```

## MCP server setup

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