# Woolworths Product Scraper – Prices, Specials & Stock (`genial_candlestand/woolworths-product-scraper`) Actor

Get Woolworths Australia product prices, was-prices, specials, unit prices, stock, barcodes and categories by keyword, barcode, URL or specials group. Optional nutrition and origin. No login, about $1.16 per 1,000 products.

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

## Pricing

Pay per event

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 Product Scraper – Prices, Specials & Stock

Get Woolworths (woolworths.com.au) product data as flat rows: shelf `price`, `wasPrice`, `savingsAmount`, unit price (`unitPriceText`), half-price and multibuy flags, `inStock`, barcode, category path, ingredients, allergens and Health Star Rating. Optionally add the nutrition panel, country of origin and aisle. No login needed.

Search by keyword, barcode or stockcode, scrape whole aisles by URL, or pull the specials catalogues (half price, buy more save more and others) without typing URLs.

### What does it do?

Give the actor search terms, woolworths.com.au links (category, specials, search or product pages) or specials groups. It returns one row per product with the online price, the saving, the unit (cup) price, availability and product facts. The output shape follows our Coles Product Scraper, so Australian supermarket prices are easy to compare side by side.

It suits price trackers, deal sites, FMCG brands, category analysts and AI agents that need to answer "what does X cost at Woolworths, and is it on special?".

### How to use

1. Open the actor in Apify Console and click **Try for free**.
2. Add search terms (for example `milk`), Woolworths URLs, or tick one or more specials groups. At least one of the three is required.
3. Set **Max products per source** and **Max products in total**, then optionally tick filters such as **Only products on special**.
4. Click **Start** and download the dataset as JSON, CSV or Excel, or read it through the API.

Agents can call it through the Apify API or the Apify MCP server with the same input.

### Pricing

Pay per event:

| Event | Price |
|---|---|
| Product (one row saved to the dataset) | $0.00116 (about $1.16 per 1,000 products) |
| Actor start | $0.00005 per GB of memory, once per run |

Nutrition, origin and aisle details cost nothing extra. Searches and pages that return no products are free. Example: 1,000 products cost about $1.16 plus the start fee. Store tier discounts may apply.

### Input

Main fields:

- `queries` – search terms, barcodes (EAN) or Woolworths stockcodes, one per item.
- `startUrls` – category, aisle, specials, search or product page links.
- `specials` – specials groups: half-price, buy-more-save-more, all, lower-shelf-price, everyday-low-price, seasonal-price, bundles, online-only-specials, everyday-market-specials-and-offers.
- `maxItemsPerSource` (default 100, max 20000) and `maxItems` (default 1000).
- `sortBy` – relevance, price, unit price or name.
- `specialsOnly`, `inStockOnly`, `includeDetails`, `includeSponsored`, `proxyConfiguration`.

```json
{
  "queries": ["milk", "tim tam"],
  "specials": ["half-price"],
  "maxItemsPerSource": 100,
  "sortBy": "priceAsc",
  "inStockOnly": true
}
```

### Output

| Field | Meaning |
|---|---|
| `id`, `barcode`, `url` | Woolworths stockcode, EAN barcode, product page |
| `title`, `brand`, `packageSize` | Product name, brand, pack size |
| `price`, `wasPrice`, `savingsAmount`, `currency` | Current price, previous price and saving (AUD) |
| `isOnSpecial`, `isHalfPrice`, `promotionText` | Offer flags and text |
| `multibuyQuantity`, `multibuyPrice` | Buy-more-save-more offer |
| `unitPrice`, `unitPriceMeasure`, `unitPriceText` | Unit (cup) price |
| `inStock`, `isAvailable`, `supplyLimit` | Availability |
| `department`, `category`, `subcategory` | Category path |
| `healthStarRating`, `ingredients`, `allergens`, `dietary` | Product facts |
| `countryOfOrigin`, `aisle`, `nutritionPer100`, `nutritionPerServe` | Filled with `includeDetails` or product URLs |
| `query`, `sourceUrl`, `position`, `scrapedAt` | Where the row came from |

Real example (shortened):

```json
{
  "id": "888140",
  "url": "https://www.woolworths.com.au/shop/productdetails/888140/woolworths-full-cream-milk",
  "title": "Woolworths Full Cream Milk 3L",
  "brand": "Woolworths",
  "packageSize": "3L",
  "barcode": "9300633556150",
  "price": 4.95,
  "wasPrice": null,
  "currency": "AUD",
  "isOnSpecial": false,
  "unitPrice": 1.65,
  "unitPriceText": "$1.65 / 1L",
  "inStock": true,
  "department": "Dairy, Eggs & Fridge",
  "category": "Milk",
  "subcategory": "Full Cream Milk",
  "healthStarRating": 4,
  "query": "milk",
  "position": 1
}
```

### Use cases

- Weekly catalogue of half-price and multibuy specials for deal sites.
- Daily price monitoring of a basket by stockcode, barcode or product URL.
- A full aisle with prices for range and assortment analysis.
- Search results for a term, in Woolworths order, for competitive research.
- Comparing Woolworths and Coles prices using the same field names.

### Limitations

- Prices are the national online default; store-specific prices are not available.
- Product ratings and review counts are not provided.
- Fields such as `wasPrice`, `healthStarRating`, `allergens` and `dietary` are empty when Woolworths does not show them. Country of origin is rarely present in listings; use `includeDetails`.
- Unavailable products have no price.
- Sponsored tiles are skipped unless `includeSponsored` is on.
- With `sortBy` unit price on search terms, Woolworths returns only products that show a unit price, so far fewer results.
- `includeDetails` makes runs slower (one extra request per product).

### FAQ

**Is it legal to scrape Woolworths?**
The actor reads publicly visible product pages and data without logging in, and returns no personal data. You are responsible for using the data in line with the site's terms and the law that applies to you.

**Can I look up one product?**
Yes: put its barcode or stockcode in `queries`, or its product page in `startUrls`.

**Why did "all specials" return fewer rows than expected?**
Each group is limited by `maxItemsPerSource`, and `maxItems` caps the whole run.

**How does it differ from other Woolworths scrapers?**
It takes search terms, barcodes, URLs and specials groups in one input, uses the same output shape as our Coles actor, and has a low per-product price.

### Other actors

- [Coles Product Scraper – Prices, Specials & Stock](https://apify.com/genial_candlestand/coles-product-scraper) – the same data shape for Coles, the other big Australian supermarket.
- [Google Trends Scraper](https://apify.com/genial_candlestand/google-trends-scraper) – search interest by region and related queries.
- [Google Ads Transparency Scraper](https://apify.com/genial_candlestand/google-ads-transparency-scraper) – ads by domain or advertiser.

# Actor input Schema

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

One per line, e.g. "milk" or "tim tam". A barcode (EAN) or Woolworths stockcode returns exactly that product.

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

woolworths.com.au links: a category or aisle (/shop/browse/dairy-eggs-fridge/milk), a specials page (/shop/browse/specials/half-price; /shop/browse/specials = every group), a search page (/shop/search/products?searchTerm=milk) or a product page (/shop/productdetails/888140/...). Page, sort and filter parameters in the link are ignored. Other links are skipped with a warning.

## `specials` (type: `array`):

Pick Woolworths specials catalogues (half price, buy more save more, all groups and others) without typing URLs. Each group is limited by Max products per source.

## `maxItemsPerSource` (type: `integer`):

Stop each search term, URL or specials group after this many products (36 products per page on the source). Use a large number, e.g. 5000, for a whole aisle or specials group.

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

Stop the whole run after this many products, whatever the number of sources. Each product row is one charged event.

## `sortBy` (type: `string`):

Order of the source's results, matters when you stop early. Note: "Unit price, low to high" on search terms makes Woolworths return only products that show a unit price (far fewer results); on URLs and specials it returns everything.

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

Return only products marked as on special (isOnSpecial). Applies to search terms, search URLs and category URLs. Specials groups and product URLs are always returned in full.

## `inStockOnly` (type: `boolean`):

Skip products that are out of stock or unavailable online (they have no price). Applies to every source.

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

Open every product's detail data for the nutrition panel (per 100 g and per serve), country of origin, aisle and all images. Same price per product, but the run is slower (one extra request per product). Product URLs always include these fields.

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

Keep the sponsored (promoted) tiles Woolworths mixes into category, specials and later search pages. They are often from other aisles. Kept rows have isSponsored = true; off by default so you pay only for real results.

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

Apify Proxy is recommended; the default datacenter proxy works on every plan. Residential AU is a slower fallback if blocks rise. A datacenter proxy with country AU is not available and is replaced by any datacenter country.

## Actor input object example

```json
{
  "queries": [
    "milk"
  ],
  "startUrls": [
    {
      "url": "https://www.woolworths.com.au/shop/browse/dairy-eggs-fridge/milk"
    }
  ],
  "specials": [
    "half-price"
  ],
  "maxItemsPerSource": 100,
  "maxItems": 1000,
  "sortBy": "relevance",
  "specialsOnly": false,
  "inStockOnly": false,
  "includeDetails": false,
  "includeSponsored": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Dataset with one row per product

## `overview` (type: `string`):

Products in the overview table view

## `runSummary` (type: `string`):

Counts, fill rates and errors of the 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 = {
    "queries": [
        "milk"
    ],
    "startUrls": [
        {
            "url": "https://www.woolworths.com.au/shop/browse/dairy-eggs-fridge/milk"
        }
    ],
    "specials": [
        "half-price"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("genial_candlestand/woolworths-product-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 = {
    "queries": ["milk"],
    "startUrls": [{ "url": "https://www.woolworths.com.au/shop/browse/dairy-eggs-fridge/milk" }],
    "specials": ["half-price"],
}

# Run the Actor and wait for it to finish
run = client.actor("genial_candlestand/woolworths-product-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 '{
  "queries": [
    "milk"
  ],
  "startUrls": [
    {
      "url": "https://www.woolworths.com.au/shop/browse/dairy-eggs-fridge/milk"
    }
  ],
  "specials": [
    "half-price"
  ]
}' |
apify call genial_candlestand/woolworths-product-scraper --silent --output-dataset

```

## MCP server setup

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