# Coles Australia Scraper (`tortuga/coles-scraper`) Actor

Scrape Coles Australia grocery products by category, search term or product URL: price, was-price, specials, multibuys, unit price, brand, size, images, nutrition.

- **URL**: https://apify.com/tortuga/coles-scraper.md
- **Developed by:** [Trevor Ortega](https://apify.com/tortuga) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 product scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Coles Australia Scraper

Scrape Coles Australia (coles.com.au) grocery products by category, search term or product URL: current price, was-price and savings, specials and half-price deals, multibuy promotions ("Buy 4 for $6.50"), unit price per kg/L, product ID, brand, package size, images, availability and category, plus ingredients, nutrition, allergens, country of origin and barcode on request. Track grocery prices, monitor promotions, build price-comparison datasets or feed a product catalogue.

Built for reliability: it reads the same page data the Coles website renders (no headless browser, no CSS selectors, no login), with browser TLS fingerprinting, automatic detection of Coles' Imperva bot challenge and retries on a fresh proxy session. You pay only for the products you get.

### What data does Coles Australia Scraper extract?

Every product (category, search or product mode):

| Field | Description |
|---|---|
| `productId`, `stockcode` | Coles product ID (the number at the end of the product URL); `stockcode` is the same value, named like the Woolworths scraper for easy joins |
| `name`, `shortName` | Product name with size ("Coles Bananas approx. 170g") and without |
| `url` | Product page URL |
| `brand` | Brand ("Coles", "Pauls", …) |
| `packageSize` | Pack size ("2L", "approx. 170g", "1 Each") |
| `price` | Current shelf price in AUD (number) |
| `wasPrice` | Previous price when the product is marked down, else `null` |
| `savingsAmount`, `savingsPercent` | `wasPrice - price` (0 when not on special) and the percentage Coles shows |
| `isOnSpecial`, `isHalfPrice`, `isOnlineSpecial` | Special, half-price and online-only special flags |
| `promotionType`, `specialType` | Coles promotion codes, e.g. `SPECIAL`, `MULTI_SAVE` |
| `specialText` | Saving badge such as "Save $3.00" |
| `promotion` | Offer text such as "Buy 4 for $6.50" or "Pick any 2 for $5" |
| `multibuy` | `{quantity, price, unitPriceText}` for multibuy deals, else `null` |
| `unitPrice`, `unitMeasure`, `unitPriceText` | Comparative unit price, e.g. `4.9`, `"1KG"`, `"$4.90 / 1KG"` |
| `isWeighted` | True for produce priced by weight (price is for the approximate pack weight) |
| `isAvailable`, `availabilityType`, `availableQuantity` | Online availability, channel (`InStoreAndOnline`, …) and stock quantity signal |
| `supplyLimit`, `promotionalLimit`, `isAgeRestricted` | Purchase limits and liquor/tobacco flag |
| `isSponsored` | Ad / cross-sell tile flag (these are skipped unless **Include sponsored tiles** is on) |
| `imageUrl`, `images` | Main product image and all images |
| `department`, `category`, `subcategory`, `breadcrumbs` | Coles taxonomy, e.g. "Fruit & Vegetables" > "Fruit" > "Bananas" |
| `description` | Short Coles description line |
| `sourceUrl`, `searchTerm`, `scrapedAt` | Category URL or search term that produced the item, and the run timestamp |

With **Include product details** on (or in product mode), each item also gets:

| Field | Description |
|---|---|
| `description` | Long product description |
| `ingredients` | Ingredient list |
| `allergens`, `allergenStatement` | Allergen list and the original statement |
| `nutrition`, `servingSize`, `servingsPerPack` | `[{name, per100g, perServe}]` nutrition table and serving information |
| `dietaryClaims`, `lifestyle` | "Gluten Free", "Vegan", … |
| `countryOfOrigin`, `countryOfOriginText`, `australianIngredientsPercent` | Country-of-origin label ("Made in Australia from at least 90% Australian ingredients") |
| `storageInstructions`, `directions`, `productWarnings` | Usage and safety information where Coles publishes it |
| `barcode` | GTIN / EAN barcode when exposed on the page |
| `additionalInfo` | All information panels as `[{title, text}]` |
| `images` | Full gallery images |

### How to use Coles Australia Scraper

1. Pick a **Mode**:
   - **Category**: paste listing URLs such as `https://www.coles.com.au/browse/fruit-vegetables`, `.../browse/dairy-eggs-fridge/milk`, `https://www.coles.com.au/on-special?filter_Special=halfprice` or `.../browse/down-down`. Every page is followed.
   - **Search**: enter terms such as `almond milk` or `dishwasher tablets`.
   - **Product**: paste product URLs or product IDs to get single products with full details.
2. Set **Max items** to cap the run (and the cost).
3. Optionally switch on **Include product details**, **Only specials**, or change the **Sort order** (price low to high, name, newest, specials first).
4. Click **Start**. Results appear in the **Dataset** tab; export as JSON, CSV or Excel, or read them through the API.

### Input example

```json
{
  "mode": "category",
  "categoryUrls": ["https://www.coles.com.au/on-special?filter_Special=halfprice"],
  "maxItems": 500,
  "onlySpecials": true,
  "includeDetails": false
}
```

Search mode:

```json
{
  "mode": "search",
  "searchTerms": ["almond milk", "oat milk"],
  "maxItems": 100,
  "sort": "priceAscending"
}
```

### Output example

```json
{
  "productId": 6979376,
  "stockcode": 6979376,
  "name": "Coles Gold Kiwifruit 1 Each",
  "shortName": "Coles Gold Kiwifruit",
  "url": "https://www.coles.com.au/product/coles-gold-kiwifruit-1-each-6979376",
  "brand": "Coles",
  "packageSize": "1 Each",
  "price": 1.8,
  "wasPrice": null,
  "savingsAmount": 0.0,
  "isOnSpecial": true,
  "isHalfPrice": false,
  "isOnlineSpecial": false,
  "promotionType": "SPECIAL",
  "specialType": "MULTI_SAVE",
  "savingsPercent": null,
  "specialText": null,
  "priceDescription": null,
  "promotion": "Buy 4 for $6.50",
  "multibuy": {
    "quantity": 4,
    "price": 6.5,
    "unitPriceText": "$1.62 / 1EA"
  },
  "unitPrice": 1.8,
  "unitMeasure": "1EA",
  "unitPriceText": "$1.80 / 1EA",
  "isWeighted": false,
  "isAvailable": true,
  "availabilityType": "InStoreAndOnline",
  "availableQuantity": 2518,
  "supplyLimit": 50,
  "promotionalLimit": 50,
  "isAgeRestricted": false,
  "isSponsored": false,
  "imageUrl": "https://cdn.productimages.coles.com.au/productimages/6/6979376.jpg",
  "images": [
    "https://cdn.productimages.coles.com.au/productimages/6/6979376.jpg"
  ],
  "department": "Fruit & Vegetables",
  "category": "Fruit",
  "subcategory": "Kiwi Fruit",
  "breadcrumbs": [
    "Fruit & Vegetables",
    "Fruit",
    "Kiwi Fruit"
  ],
  "description": "KIWIFRUIT:GOLD 1 EACH",
  "sourceUrl": "https://www.coles.com.au/browse/fruit-vegetables",
  "searchTerm": null,
  "scrapedAt": "2026-09-14T05:04:00+00:00"
}
```

### How to scrape Coles specials and half-price deals

Use category mode with `https://www.coles.com.au/on-special` (all specials), `https://www.coles.com.au/on-special?filter_Special=halfprice` (half price) or `...?filter_Special=multibuy`, or any category with **Only specials** on. `wasPrice`, `savingsAmount`, `isHalfPrice` and `specialText` tell you the size of a price cut; `promotion` and `multibuy` capture "Buy 2 for $X" deals. Run it daily on a schedule to build a price history.

### How to get Coles prices per kg or per litre

Every item carries `unitPrice` and `unitMeasure` (for example `4.9` and `1KG` for bananas) plus the display string `unitPriceText`. Produce sold by weight has `isWeighted: true`: `price` is for the approximate weight in `packageSize` ("approx. 170g") and the unit price is the per-kg shelf price.

### Compare Coles and Woolworths prices

This Actor is the Coles half of a matched pair. The [Woolworths Australia Scraper](https://apify.com/tortuga/woolworths-scraper) uses the same input (`mode`, `categoryUrls`, `searchTerms`, `productUrls`, `maxItems`, `includeDetails`, `onlySpecials`) and the same output field names (`name`, `brand`, `packageSize`, `price`, `wasPrice`, `savingsAmount`, `isOnSpecial`, `promotion`, `unitPrice`, `unitMeasure`, `stockcode`, …), so you can run the same search terms on both and put the datasets side by side in one spreadsheet. `unitPrice` + `unitMeasure` is the fairest comparison across different pack sizes.

### How to track a specific product's price

Use product mode with the product URL or ID (`8150288`). Each run returns the current `price`, `wasPrice`, specials and availability plus ingredients, nutrition and origin. Schedule the Actor and diff the dataset over time.

### Does it work without login or a browser?

Yes. The Actor only reads public pages and never logs in. Coles uses Imperva bot protection; when a request is challenged, the Actor detects it and retries on a new proxy session with a back-off, which is why Apify Proxy is on by default. If a run logs repeated challenges, switch the proxy to residential (Australia). Prices are the standard online prices Coles shows before a store or delivery address is chosen; store-specific pricing is not covered.

### Proxy note

Coles uses Imperva bot protection that blocks datacenter IP addresses, so the Actor uses Apify residential proxies located in Australia by default. Proxy traffic is billed to your Apify account at the standard residential rate.

### Pricing

Pay per result: a small fee per product saved, plus a small extra fee per product page opened when **Include product details** is on or in product mode. There is no subscription and no start fee; Apify's free plan is enough to try it.

### Integrations and API

Use the run in Zapier, Make, n8n, Google Sheets, or call it from Python/Node with the Apify client. See the **API** tab for ready-made snippets.

### Is it legal to scrape Coles?

This Actor collects only publicly available, non-personal product data (prices, descriptions, nutrition). It does not log in and does not collect any user or reviewer information. You are responsible for how you use the data and for complying with Coles' terms and applicable law.

### Support

Found a bug or need a field added? Open an issue in the **Issues** tab; it is usually answered within a day.

# Actor input Schema

## `mode` (type: `string`):

What to scrape: `category` walks Coles listing pages (Category URLs), `search` runs search terms, `product` fetches individual products by URL or product ID (always with full details).

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

Coles listing URLs, one per line: a department (https://www.coles.com.au/browse/fruit-vegetables), a category (.../browse/dairy-eggs-fridge/milk), specials (https://www.coles.com.au/on-special, .../on-special?filter\_Special=halfprice) or Down Down (.../browse/down-down). Filters and sort already in the URL are kept. Every page is followed automatically (48 products per page). Used when Mode is `category`.

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

Search queries such as `almond milk` or `dishwasher tablets`. Each term is paginated like the website search. Used when Mode is `search`.

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

Product page URLs like https://www.coles.com.au/product/coles-full-cream-milk-3l-8150288. Used when Mode is `product`.

## `productIds` (type: `array`):

Coles product IDs (the number at the end of the product URL), e.g. `8150288`. Used when Mode is `product`, together with or instead of Product URLs.

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

Stop after this many products in total (across all categories / search terms). Keeps cost predictable.

## `includeDetails` (type: `boolean`):

Also open every product page to add the long description, ingredients, nutrition table, allergens, dietary claims, country of origin, storage instructions and all gallery images. One extra request per product, charged extra (see pricing).

## `onlySpecials` (type: `boolean`):

Keep only products on special: price cuts (`wasPrice`), half price, multibuys such as `Buy 2 for $6` and other Coles specials. The site's own specials filter is applied first, so fewer pages are fetched.

## `includeSponsored` (type: `boolean`):

Listing pages occasionally carry ad or cross-sell tiles that belong to other aisles. Off by default so the dataset matches the category's real product list; switch on to keep them (flagged with `isSponsored: true`).

## `sort` (type: `string`):

Order in which Coles returns products (matters when Max items cuts a category short).

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

Coles' bot protection blocks datacenter IPs, so residential Apify Proxy in Australia is the default. Proxy usage is billed to your account.

## Actor input object example

```json
{
  "mode": "category",
  "categoryUrls": [
    "https://www.coles.com.au/browse/fruit-vegetables"
  ],
  "searchTerms": [
    "almond milk"
  ],
  "maxItems": 200,
  "includeDetails": false,
  "onlySpecials": false,
  "includeSponsored": false,
  "sort": "relevance",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "AU"
  }
}
```

# Actor output Schema

## `results` (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 = {
    "categoryUrls": [
        "https://www.coles.com.au/browse/fruit-vegetables"
    ],
    "searchTerms": [
        "almond milk"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "AU"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("tortuga/coles-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 = {
    "categoryUrls": ["https://www.coles.com.au/browse/fruit-vegetables"],
    "searchTerms": ["almond milk"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "AU",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("tortuga/coles-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 '{
  "categoryUrls": [
    "https://www.coles.com.au/browse/fruit-vegetables"
  ],
  "searchTerms": [
    "almond milk"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "AU"
  }
}' |
apify call tortuga/coles-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tortuga/coles-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/a9DFFQsjATeDimS4r/builds/0EL4rPgibOAJ2G33e/openapi.json
