# ALDI AU Scraper (Products, Prices, Unit Prices) (`webdatatools/aldi-au-scraper`) Actor

Scrape ALDI Australia product search results by keyword: product name, brand, pack size, price, was-price, unit price, category, image, product link and SKU.

- **URL**: https://apify.com/webdatatools/aldi-au-scraper.md
- **Developed by:** [Murat Uzun](https://apify.com/webdatatools) (community)
- **Categories:** E-commerce, Lead generation, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.30 / 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

### What is ALDI AU Scraper?

ALDI AU Scraper collects product search results from aldi.com.au, the Australian arm of the discount supermarket chain. Give it a keyword such as `milk` or `oat milk` and it returns one row per product: name, brand, pack size, price in AUD, unit price per 100 g or per litre, category, image, product link and SKU. It reads the JSON API that the ALDI website search page calls, so no browser runs and no login is needed.

### What data does ALDI AU Scraper extract?

| Field | Type | Description |
|---|---|---|
| `sku` | string | ALDI product code (stable key). |
| `name` | string | Product name, often with the pack size. |
| `brand` | string | Brand as listed. |
| `packageSize` | string | Selling size, e.g. `1 l`, `168 g`. |
| `price` | number | Current price in AUD. Converted from the cents the API returns. |
| `priceText` | string | Price as shown on the site, e.g. `$3.99`. |
| `wasPrice` | number | Previous price when it is above `price`. Not observed in the 120 test rows (see Limitations). |
| `onSale` | boolean | True when the product carries an on-sale date (ALDI "special buys" flag). |
| `savingsText` | string | Savings text when the site shows one. Not observed in the test rows. |
| `unitPrice` | number | Price per unit of measure, e.g. per 100 g or per 1 L. |
| `unitPriceText` | string | Unit price as shown, e.g. `$2.38 per 100 g`. |
| `unitOfMeasure` | string | Unit of the unit price, e.g. `100 g`. |
| `category` | string | Lowest category level, e.g. `Milk`, `Confectionery`. |
| `categoryPath` | string | Full category path, e.g. `Dairy, Eggs & Fridge > Milk`. |
| `imageUrl` | string | Product image, 500 px wide. |
| `url` | string | Product page on aldi.com.au (`/product/<slug>-<sku>`). |
| `notForSale` | boolean | The API's `notForSale` flag, copied as returned. It was true for every product in the test runs, so do not read it as "unavailable". |
| `discontinued` | boolean | Discontinued flag from the API. |
| `searchTerm`, `page`, `offset`, `position` | mixed | Keyword, page number, result offset and rank within the keyword. |
| `totalResults` | number | Total hits the API reported for the keyword. |
| `scrapedAt` | string | ISO time of the scrape. |

### How to use ALDI AU Scraper

1. Open the Actor and enter one or more keywords separated by `;`, for example `milk; bread; eggs`.
2. Set **Max products per search** (default 100). Each keyword is scraped separately, up to this limit.
3. Click **Start**, then download the dataset as JSON, CSV or Excel, or read it through the API.

### Example input

```json
{
    "keywords": "milk; bread",
    "maxProducts": 30
}
```

### Example output

Real rows from a run on 2026-10-23 (keyword `milk`, first result):

```json
[
  {
    "sku": "000000000538441002",
    "name": "Milk Mouse - Milk Chocolate 168g",
    "brand": "CHOCEUR",
    "packageSize": "168 g",
    "price": 3.99,
    "priceText": "$3.99",
    "wasPrice": null,
    "onSale": false,
    "savingsText": null,
    "unitPrice": 2.38,
    "unitPriceText": "$2.38 per 100 g",
    "unitOfMeasure": "100 g",
    "category": "Confectionery",
    "categoryPath": "Pantry > Confectionery",
    "imageUrl": "https://dm.apac.cms.aldi.cx/is/image/aldiprodapac/product/jpg/scaleWidth/500/d0097d9d-25d6-4cd1-b1dd-1ea5f7a154ba/choceur-milk-mouse-milk-chocolate-168g",
    "url": "https://www.aldi.com.au/product/choceur-milk-mouse-milk-chocolate-168g-000000000538441002",
    "notForSale": true,
    "discontinued": false,
    "searchTerm": "milk",
    "page": 1,
    "offset": 0,
    "position": 1,
    "totalResults": 95
  }
]
```

### Input parameters

| Parameter | Default | Meaning |
|---|---|---|
| `keywords` | `milk` | Search terms separated by `;`. |
| `maxProducts` | 100 | Products per keyword, 1 to 5000. |

### Pricing

Pay per result: **$0.30 per 1,000 products** on every tier (Apify's minimum tier price). The Actor start is charged separately ($0.05 per 1,000 starts). Measured on 2026-10-23: a 120-product run cost $0.0023 in total at the default 4 GB memory; a 465-product run (4 keywords) cost $0.0037 at 512 MB. Neither run used proxy traffic. The closest public ALDI AU scraper, `dromb/aldi-au-product-search-catalog-unofficial` (268 monthly users on 2026-10-23), charges $0.40 per 1,000 results.

### ALDI AU Scraper vs. the alternative

The closest public ALDI AU scraper charges $0.40 per 1,000 results. This Actor charges $0.30 per 1,000 and returns the unit price, pack size, category path and SKU in every row.

### Using ALDI AU Scraper with AI agents / MCP

The Actor is pay per result and takes a plain keyword input, so an AI agent can call it through the Apify MCP server with `{"keywords": "milk", "maxProducts": 50}`. The output is one flat row per product.

### FAQ

**Does it need an ALDI account?** No. It reads the public product search API.

**Are prices per store?** No. The API returns the national price shown for the walk-in service type. Store-level differences are not covered.

**Why is `wasPrice` empty?** In the 120 rows of the 2026-10-23 test runs, no product had a was-price field, so that path is untested against live specials. `onSale` comes from the on-sale date that the API did return for four rows.

**Is stock available?** The API response has no per-product stock field. The Actor does not guess stock.

**Is the `url` verified?** Yes for the test product: `https://www.aldi.com.au/product/choceur-milk-mouse-milk-chocolate-168g-000000000538441002` returned HTTP 200 from an Apify cloud run.

**What if the same product matches two keywords?** It is returned once, under the first keyword that found it, and counted once in the charge.

**What happens when ALDI blocks the Actor?** The Actor retries after short waits and then switches to Apify's Australian residential proxy for the rest of the run. Searches that still fail go into the `ERRORS` record and are not charged.

### Limitations

- Keyword search only. No category browsing and no store-level prices.
- No stock field in the API.
- `wasPrice` and `savingsText` were not seen in live rows yet.
- Results are capped by `maxProducts`. The test keywords returned 95 hits (`milk`).

### Support

Open an issue on the Actor's Issues tab. Include the keyword, the input JSON and the run ID.

# Actor input Schema

## `keywords` (type: `string`):

What to search for on aldi.com.au, several separated by `;` (e.g. `milk; bread; eggs`).

## `maxProducts` (type: `integer`):

For each keyword (24 per page).

## Actor input object example

```json
{
  "keywords": "milk",
  "maxProducts": 100
}
```

# Actor output Schema

## `results` (type: `string`):

All products from this 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 = {
    "keywords": "milk"
};

// Run the Actor and wait for it to finish
const run = await client.actor("webdatatools/aldi-au-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 = { "keywords": "milk" }

# Run the Actor and wait for it to finish
run = client.actor("webdatatools/aldi-au-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 '{
  "keywords": "milk"
}' |
apify call webdatatools/aldi-au-scraper --silent --output-dataset

```

## MCP server setup

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