# Woolworths Products Scraper (`automation-lab/woolworths-australia-grocery-products-prices`) Actor

Search Woolworths Australia and export product IDs, brands, pack sizes, current and unit prices, promotions, availability, categories, images, and timestamped source records.

- **URL**: https://apify.com/automation-lab/woolworths-australia-grocery-products-prices.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.96 / 1,000 item extracteds

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 Products Scraper

Search Woolworths Australia and turn current **Woolworths products** into structured, timestamped records for grocery price and assortment monitoring.

The Actor accepts ordinary product, brand, or grocery-category searches and exports stable product IDs, GTIN barcodes, brands, pack sizes, online prices, unit prices, promotion fields, availability, categories, images, product links, and source timestamps.

It is unofficial and is not affiliated with Woolworths Group.

### What does this Actor do?

The Actor runs the supplied searches against the public Woolworths Australia storefront.

For every accepted product card it normalizes:

- identity and barcode fields;
- display name, brand, and pack size;
- current, prior, savings, and unit-price fields;
- special and half-price indicators;
- online availability and stock signals;
- department, category, and subcategory fields;
- large product image and canonical product URL;
- the source search and collection timestamp.

Results go to the run's default Apify dataset, ready for JSON, CSV, Excel, XML, RSS, or API delivery.

### Who is it for?

#### Retail and pricing analysts

Build comparable grocery baskets and observe current price or promotion changes across scheduled snapshots.

#### FMCG and brand teams

Measure which products appear for branded or category searches and retain product identity, category, and sponsored-placement signals.

#### Data engineers

Feed normalized Woolworths product records into a warehouse, spreadsheet, dashboard, or price-history pipeline.

#### Researchers and developers

Collect small, source-attributed product samples without maintaining browser automation or parsing storefront markup.

### Why use this Woolworths products scraper?

- **Monitoring-ready records:** each item includes a stable stock code, source URL, and `scrapedAt` timestamp.
- **Price context:** current price, prior price, savings amount, unit price, and promotion state are kept together.
- **Useful product context:** brand, pack size, category, availability, image, and canonical URL are included.
- **Bounded runs:** `maxItems` provides an explicit cost and volume ceiling.
- **Multiple searches:** submit up to 20 terms in one run and deduplicate products by Woolworths stock code.
- **Organic-only option:** exclude sponsored cards when search-position analysis should use organic results only.
- **Australian routing included:** the Actor manages the storefront session and Australian proxy route automatically.

### What data can I extract?

| Field | Meaning |
| --- | --- |
| `query` | Search term that produced the record |
| `productId` | Stable Woolworths stock code |
| `barcode` | GTIN barcode when published |
| `name` | Display name, normally including size |
| `brand` | Product brand when exposed |
| `packSize` | Source pack-size label |
| `price` | Current online price in AUD |
| `unitPrice` | Numeric comparison price |
| `unitMeasure` | Comparison unit such as `1L` |
| `unitPriceFormatted` | Source-formatted unit-price label |
| `promotion` | Special, half-price, was-price, savings, label, and type fields |
| `available` | Current purchasable-online signal |
| `inStock` | Current online stock signal |
| `onlineOnly` | Online-only product flag |
| `sponsored` | Sponsored search-card flag |
| `supplyLimit` | Published purchase limit when exposed |
| `department` | Woolworths SAP department |
| `category` | Woolworths SAP category |
| `subcategory` | Woolworths SAP subcategory |
| `imageUrl` | Large product image URL |
| `productUrl` | Canonical Woolworths product URL |
| `sourceUrl` | Search URL used for the snapshot |
| `scrapedAt` | ISO 8601 collection timestamp |

Fields that Woolworths does not expose for a product are returned as `null` rather than invented.

### Getting started

1. Open the Actor in Apify Console.
2. Add one or more terms to **Search terms**.
3. Choose a **Maximum products** limit.
4. Keep **Include sponsored products** enabled for the complete returned search feed, or disable it for organic-only records.
5. Click **Start**.
6. Open the **Results** dataset view.
7. Export the records or connect the dataset API to your workflow.

A practical first run is:

```json
{
  "queries": ["milk", "bread", "eggs"],
  "maxItems": 30,
  "includeSponsored": true
}
```

### Input parameters

#### `queries`

Required array of 1–20 strings.

Each value must contain 2–100 characters and may be a product, brand, dietary need, or grocery-category search.

Examples include `milk`, `Arnott's Tim Tam`, `oat milk`, and `vegan cheese`.

#### `maxItems`

Optional integer from 1 to 5,000.

The limit applies across all searches after product-ID deduplication.

Default: `100`.

#### `includeSponsored`

Optional boolean.

Set it to `false` when you want organic product cards only.

Default: `true`.

### Example output

A current product record has this shape:

```json
{
  "query": "milk",
  "productId": "888140",
  "barcode": "9300633556150",
  "name": "Woolworths Full Cream Milk 3L",
  "brand": "Woolworths",
  "packSize": "3L",
  "price": 4.95,
  "currency": "AUD",
  "unitPrice": 1.65,
  "unitMeasure": "1L",
  "unitPriceFormatted": "$1.65 / 1L",
  "promotion": {
    "isOnSpecial": false,
    "isHalfPrice": false,
    "wasPrice": 4.95,
    "savingsAmount": 0,
    "label": null,
    "type": null
  },
  "available": true,
  "inStock": true,
  "onlineOnly": false,
  "sponsored": false,
  "supplyLimit": 36,
  "department": "FRESH CONVENIENCE",
  "category": "DAIRY - MILK",
  "subcategory": "DAIRY - MILK",
  "imageUrl": "https://cdn0.woolworths.media/content/wowproductimages/large/888140.jpg",
  "productUrl": "https://www.woolworths.com.au/shop/productdetails/888140/woolworths-full-cream-milk",
  "sourceUrl": "https://www.woolworths.com.au/shop/search/products?searchTerm=milk",
  "scrapedAt": "2026-09-19T06:36:48.932Z"
}
```

Prices and availability are snapshots, not historical records supplied by Woolworths.

Schedule repeated runs and retain datasets in your own destination when you need history.

### How much does it cost to monitor Woolworths product prices?

The Actor uses pay-per-event pricing.

A run has one **Start** event and one **Item processed** event for every product saved to the default dataset.

The current BRONZE prices are:

- **Start:** $0.005 per run;
- **Item extracted:** $0.0016 per saved product.

At those prices, estimated Actor charges are:

| Saved products | Estimated charge |
| ---: | ---: |
| 10 | $0.021 |
| 100 | $0.165 |
| 1,000 | $1.605 |

Higher subscription tiers receive the lower item rates shown in Apify Console.

These examples estimate Actor event charges only.

Actual platform billing can also reflect plan rules, limits, refunds, fraud, disputes, taxes, corrections, and clawbacks.

Use `maxItems` to set a predictable output ceiling.

### Recurring price monitoring workflow

1. Choose a stable list of basket, brand, or category terms.
2. Keep `includeSponsored` consistent between runs.
3. Schedule the Actor daily or weekly.
4. Export each dataset with its `scrapedAt` value.
5. Join snapshots on `productId`.
6. Compare `price`, `promotion`, `available`, and category fields.
7. Alert only after your own validation rules confirm a meaningful change.

The Actor emits current snapshots; it does not merge past runs or send alerts itself.

### Spreadsheet and data-pipeline integrations

Use Apify integrations to send the dataset to Google Sheets, Make, Zapier, Slack, webhooks, or a custom destination.

For warehouses, poll the default dataset endpoint after the run succeeds.

For idempotent loads, use the run ID plus `productId` as a composite ingestion key.

For time-series tables, store `scrapedAt` alongside every measurement rather than overwriting the prior record.

### Run through the Apify API with cURL

Set your token in an environment variable rather than putting it in source code.

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~woolworths-australia-grocery-products-prices/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries":["milk","bread"],"maxItems":50,"includeSponsored":true}'
```

Wait for the run to finish, then read its default dataset.

### Run with JavaScript

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

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

const run = await client.actor(
  'automation-lab/woolworths-australia-grocery-products-prices',
).call({
  queries: ['milk', 'bread'],
  maxItems: 50,
  includeSponsored: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Run with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor(
    'automation-lab/woolworths-australia-grocery-products-prices'
).call(run_input={
    'queries': ['milk', 'bread'],
    'maxItems': 50,
    'includeSponsored': True,
})

items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use with MCP and AI assistants

Connect Claude Code to the Apify MCP server:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/woolworths-australia-grocery-products-prices"
```

#### Claude Desktop, Cursor, and VS Code setup

Claude Desktop, Cursor, and VS Code can use this equivalent MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/woolworths-australia-grocery-products-prices"
    }
  }
}
```

Example prompts:

- “Search Woolworths for milk, bread, and eggs and return 50 current product records.”
- “Collect organic Arnott's Tim Tam search results without sponsored products.”
- “Run the plant-based grocery searches weekly and compare product IDs and prices with the previous dataset.”

Always inspect the proposed input and cost ceiling before allowing an assistant to start a large run.

### Reliability, retries, and failure behavior

Woolworths protects its Australian storefront and may reject mismatched network identities.

The Actor creates an Australian residential session, bootstraps storefront cookies, and reuses that identity for the catalog request.

On a transport, challenge, or invalid-response failure, it rotates the complete session and retries up to three times.

If all attempts fail, the run fails with a non-zero status instead of returning a misleading empty success.

Malformed inputs also fail before network requests begin.

### Limits and data interpretation

- The supported discovery mode is keyword search.
- Search ranking and sponsored placement can change between runs.
- Woolworths may return related or corrected products for low-confidence queries.
- Prices and availability can depend on the fulfilment store selected by the public storefront session.
- `available` and `inStock` are source signals, not a reservation or guarantee.
- Categories are returned only when Woolworths publishes the relevant SAP attributes.
- Product detail nutrition, ingredients, reviews, and historical prices are outside this Actor's contract.
- The Actor does not download images; it exports their source URLs.
- Large limits take longer and consume more residential proxy transfer.

### Tips for better results

Use specific branded terms when you need a narrow product family.

Use several separate category terms when you need a broad basket.

Keep the same input, schedule, and sponsored setting for comparable recurring snapshots.

Deduplicate downstream on `productId`, not product name.

Treat null values as “not exposed in this response,” not as false or zero.

Start with 25–100 products before increasing the limit.

### AI, privacy, and data retention

The Actor does not call an AI model and does not send data to an AI provider.

User-supplied search terms and public catalog requests transit Apify's Australian residential proxy infrastructure and Woolworths Australia.

The Actor creates no external cache or database of its own.

Run datasets, key-value stores, and logs follow the retention settings of the user's Apify account and can be deleted with Apify storage controls.

Optional MCP clients may process inputs and results under the user's own model and client configuration.

### Responsible use and legality

This Actor accesses publicly visible Woolworths Australia product-search data.

You are responsible for ensuring that your use complies with Woolworths terms, Apify policies, applicable laws, and contractual restrictions.

Do not use the Actor to overload the source, evade access controls for private data, reproduce protected content unlawfully, or make automated purchasing decisions without validation.

Product names, images, brands, and other source content may be protected by intellectual-property rights.

Collect only what you need and apply appropriate retention and access controls.

### Troubleshooting

#### The run fails after several session attempts

Check the run log for bootstrap, HTTP, or response-shape errors.

Retry later with a small input; do not loop failed runs rapidly.

The Actor manages its own required Australian proxy route, so custom proxy configuration is not needed.

#### A strange query returns related products

Woolworths can correct or broaden low-confidence searches.

Use more specific terms and validate `query`, `name`, and `brand` downstream.

#### I received fewer records than `maxItems`

The limit is a ceiling, not a guaranteed count.

The source may have fewer results, sponsored filtering may remove items, and duplicate product IDs across queries are saved only once.

#### Some category or barcode fields are null

Those fields are conditional on the public source response.

The Actor does not infer missing values.

#### Can I scrape product URLs directly?

Not in this version.

Use search terms and the returned `productUrl` values; direct detail-page enrichment is outside the supported contract.

### FAQ

#### Does it work outside Australia?

Yes, runs can be started from anywhere because the Actor uses Australian residential routing for the Woolworths storefront.

#### Does it provide historical prices?

No.

It provides timestamped current snapshots that you can schedule and store to build your own history.

#### Does it include specials?

Yes.

It exports special, half-price, was-price, savings, promotion-label, and promotion-type fields when Woolworths exposes them.

#### Does it charge for failed or filtered records?

The item event is charged only for accepted product records written to the dataset.

The one-time start event still applies when a run begins.

#### Can it monitor a whole category?

You can search category phrases such as `oat milk` or `vegan cheese`.

Direct category-URL crawling is not currently supported.

#### Is the Actor affiliated with Woolworths?

No.

It is an independent, unofficial automation product.

### Related Automation Lab Actors

For grocery monitoring outside Australia, consider:

- [ASDA Grocery Products & Prices Scraper](https://apify.com/automation-lab/asda-grocery-products-prices)
- [Superstore & No Frills Grocery Prices](https://apify.com/automation-lab/superstore-no-frills-grocery-prices)

Choose this Actor when the required source is Woolworths Australia and the buyer job is search-based product, price, promotion, and availability monitoring.

### Support

When reporting a problem, include the run URL, non-sensitive input, expected result, and a short description of the unexpected behavior.

Do not paste your Apify token or other credentials into support messages.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/woolworths-australia-grocery-products-prices/changelog.md

# Actor input Schema

## `queries` (type: `array`):

One to 20 product, brand, or grocery-category searches to run on Woolworths Australia.

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

Stop after saving this many unique products across all searches.

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

Include sponsored product cards returned by Woolworths search. Disable for organic-only search monitoring.

## Actor input object example

```json
{
  "queries": [
    "milk",
    "bread",
    "eggs"
  ],
  "maxItems": 20,
  "includeSponsored": true
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing all extracted Woolworths product records.

# 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 = {
    "queries": [
        "milk",
        "bread",
        "eggs"
    ],
    "maxItems": 20,
    "includeSponsored": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/woolworths-australia-grocery-products-prices").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 = {
    "queries": [
        "milk",
        "bread",
        "eggs",
    ],
    "maxItems": 20,
    "includeSponsored": True,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/woolworths-australia-grocery-products-prices").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 '{
  "queries": [
    "milk",
    "bread",
    "eggs"
  ],
  "maxItems": 20,
  "includeSponsored": true
}' |
apify call automation-lab/woolworths-australia-grocery-products-prices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/woolworths-australia-grocery-products-prices"
        }
    }
}
```

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/zqz40sVgLsqqHYSEG/builds/bsbqO84H9E2jRqlb1/openapi.json
