Australia Supermarket Price Scraper: Coles, Woolworths, Aldi avatar

Australia Supermarket Price Scraper: Coles, Woolworths, Aldi

Pricing

from $1.20 / 1,000 products

Go to Apify Store
Australia Supermarket Price Scraper: Coles, Woolworths, Aldi

Australia Supermarket Price Scraper: Coles, Woolworths, Aldi

Prices for Coles, Woolworths and Aldi Australia in one schema: price, was-price, unit price, promotion, EAN where published, store ID, scrapedAt. Use it to compare a product across the three shops or read Aldi Special Buys. Not for NZ or other shops. Pay per product returned plus $0.005 a run.

Pricing

from $1.20 / 1,000 products

Rating

0.0

(0)

Developer

Russell Yapp

Russell Yapp

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

0

Monthly active users

4 days ago

Last modified

Categories

Share

Australia Supermarket Price Scraper: Coles, Woolworths and Aldi prices API

Current shelf prices from Coles, Woolworths and Aldi Australia in one schema. Each row is one product at one shop: price, unitPrice, wasPrice, promotionText, storeId and scrapedAt, plus ean where the shop publishes one and a matchKey join key. Australia only, three shops, charged per product returned plus a $0.005 start fee.

Cost. On the Free plan: $0.005 per run plus $0.002 per product. The default run (a search for "milk" in all three shops, up to 60 rows) costs up to $0.125 ($0.077 on Gold). A run that returns nothing costs only the start fee, and if a shop blocks the run, that shop stops and you pay only for the rows already returned (plus the start fee). Nothing else is charged on a search, category, product or Special Buys run. The default run usually takes about a minute.

ModeUse it toInputExample question
searchFind products by keyword in one or more shopsqueries, retailers"What does full cream milk cost at Coles and Woolworths?"
categoryRead the products on a shop's category pagecategoryUrls"What do the products in this Coles milk category cost?" (up to maxItems rows)
productRead named product pagesproductUrls"What is the unit price of this product at each shop?" (give one URL per shop)
specialBuysRead Aldi's dated Special Buys dropsspecialBuysDrops (optional)"Which Aldi Special Buys are coming up, and what do they cost?"

Sample questions an agent can answer with one run: "What does full cream milk cost at Coles and Woolworths?", "Which Aldi Special Buys are coming up?" and "What is the unit price of this product at each shop?" (give one URL per shop)

{
"retailer": "woolworths", "retailerProductId": "204746", "ean": ["9310036039488"],
"name": "Pauls Smarter White Low Fat Milk 2L", "brand": "Pauls", "packSize": "2L",
"price": 4.6, "wasPrice": 5.1, "unitPrice": {"value": 2.3, "measure": "l"},
"loyaltyPrice": null, "promotionText": "Special", "promotionEndsAt": null, "inStock": true,
"categoryPath": ["Dairy, Eggs & Fridge", "Milk"],
"url": "https://www.woolworths.com.au/shop/productdetails/204746/pauls-smarter-white-low-fat-milk",
"imageUrl": "https://cdn0.woolworths.media/content/wowproductimages/large/204746.jpg",
"rating": null, "scrapedAt": "2026-10-08T06:00:19Z",
"matchKey": "pauls smarter white low fat milk 2l 2000ml",
"currency": "AUD", "market": "au", "storeId": "1101", "onSaleDate": null
}

Run it with the default input: click Start.

16-second demo on YouTube: https://youtu.be/IrLdJdF8pBY

Sample output row

{
"retailer": "coles",
"retailerProductId": "1902454",
"ean": ["9310036048985"],
"matchKey": "pauls zymil lactose free full cream milk 2000ml",
"name": "Pauls Zymil Lactose Free Full Cream Milk",
"brand": "Pauls",
"packSize": "2L",
"price": 5.95,
"wasPrice": 6.9,
"unitPrice": { "value": 2.98, "measure": "l" },
"loyaltyPrice": null,
"promotionText": "save $0.95",
"promotionEndsAt": null,
"inStock": true,
"categoryPath": ["Dairy, Eggs & Fridge", "Milk", "Long Life Milk"],
"url": "https://www.coles.com.au/product/pauls-zymil-lactose-free-full-cream-milk-2l-1902454",
"imageUrl": "https://cdn.productimages.coles.com.au/productimages/...",
"rating": null,
"currency": "AUD",
"market": "au",
"storeId": "7674",
"onSaleDate": null,
"scrapedAt": "2026-09-24T10:15:00Z"
}

ean, matchKey, name, brand, packSize, price, wasPrice, promotionText, inStock, storeId, currency and market are from a captured Coles product page (24 Sep 2026, product 1902454). unitPrice, categoryPath, imageUrl and scrapedAt are illustrative, not real. rating, promotionEndsAt and onSaleDate are always null for Coles rows; loyaltyPrice is always null for Coles and Woolworths (neither retailer's public data exposes a loyalty price).

What you get: the Australian supermarket prices dataset

RetailerModesBarcode (EAN) coveragePromotion fieldsStock
Colessearch, category, productWith colesProductDetails on (off by default), on nearly every row, a small number without one; off, empty ean and a join on matchKey. Product mode always looks it upwasPrice on a markdown; promotionText carries multi-buy specials (e.g. Pick any 2 for $5) or a markdown's save text (e.g. save $0.80)Coles's own availability flag
Woolworthssearch, category, productOn nearly every row; a barcode that fails check-digit validation is left out and that row ships with an empty eanwasPrice on a markdown; promotionText carries the special's own tag text, a Special/25% Off-style badge, or 1/2 PriceWoolworths' own IsInStock flag
Aldisearch, category, product, Special BuysNone — Aldi publishes no barcode in its listing API, product API or product pages, so rows carry an empty ean and join on matchKeywasPrice when Aldi shows a was price; promotionText only on Special Buys rows (the on-sale line, e.g. On Sale Wed 07 Oct)Not reported online (inStock is null)

Every row also carries matchKey, a normalised brand + name + pack size, so you can join Aldi products to Coles and Woolworths even without a barcode.

One run reads Coles, Woolworths and Aldi Australia and returns the same row shape for all three, with a matchKey to join the same product across shops. ean holds a check-digit-validated GTIN-13 where the retailer publishes one: on nearly every Woolworths row, on Coles rows when colesProductDetails is on, and never for Aldi, which publishes no barcode. Specials come through as wasPrice and promotionText, and specialBuys mode returns Aldi's dated Special Buys drops with each drop's date in onSaleDate. If half or more of a retailer's products in a run cannot be read into rows, which usually means the site has changed, the run summary marks that retailer degraded instead of ok and the run's status message says so. Stores are fixed, not chosen: Coles is priced as shown to a visitor with no store selected (store 7674), Aldi likewise (service point G452), and Woolworths at whatever store it assigns a logged-out session, usually 1101 and sometimes a regional store, which changes the range. Every row records its store in storeId. The Actor has no store or postcode input, so it cannot return prices for a store you pick.

This Actor is not affiliated with, endorsed by, or partnered with Coles, Woolworths or Aldi. Retailer names are used only to describe the public product data returned.

Coles, Woolworths and Aldi: what each retailer exposes

Coles scraper and Coles API. This Coles price scraper returns Coles's shelf price, unit price and current specials. Barcode lookup is opt-in: with colesProductDetails on, it adds a GTIN-13 barcode to nearly every row (a small number ship without one), at one extra request per product. Prices are as shown to a visitor with no store selected (store 7674); store selection is not offered in v0.1.

Woolworths scraper and Woolworths API. This Woolworths price scraper returns Woolworths' shelf price, a GTIN-13 barcode on nearly every row (a barcode that fails check-digit validation is left out and that row ships with an empty ean), unit price where Woolworths publishes one, and current specials. Woolworths assigns every logged-out session a fulfilment store and ranges and prices products per store; the Actor cannot choose one (Woolworths only offers store selection after login), so rows are priced at the store Woolworths assigns: usually 1101 (national default). When it assigns another store, the Actor opens up to two fresh sessions before reading any product, to get 1101; if none does, rows are priced at the store assigned, which changes the range. Every row records the store as storeId. Products the assigned store doesn't range or price are skipped rather than returned as $0 rows.

Aldi Australia prices. This Aldi Australia price scraper returns Aldi's own in-store reference prices, as shown to a visitor with no store selected (service point G452), exactly as published online. Aldi exposes no barcode anywhere — its listing API, product API and product pages all carry none — so rows carry an empty ean array and a matchKey (normalised name and pack size) instead, and storeId is G452. Aldi reports no stock online, so inStock is null. Aldi rows are usually the fastest of the three.

Aldi Special Buys. Special Buys mode (mode: "specialBuys") returns the products of Aldi Australia's Special Buys drops: the dated non-grocery and seasonal releases Aldi puts in store on Wednesdays and Saturdays, which sit outside its normal categories. It reads the drops Aldi's Special Buys page lists (usually one to two weeks ahead): by default every drop dated today or later (Sydney date), including drops not yet on sale, or the dates you give in specialBuysDrops. Rows have the same shape as every other row: onSaleDate is the drop date, promotionText the on-sale line (e.g. On Sale Wed 07 Oct), and inStock and promotionEndsAt are null (Aldi sells Special Buys while stocks last and publishes no end date). A drop is usually 50 to 100 products, so set maxItems to cover the drops you want. Rows are charged like any other product row.

Australian grocery price tracking and other use cases

  • Price-comparison apps and deal-tracking channels
  • Competitor and retail-analytics price monitoring
  • Inflation trackers and basket-of-goods research
  • Tracking Aldi's weekly Special Buys drops and their prices
  • AI agents doing Australian grocery price or basket lookups
  • Building a supermarket price comparison across Coles, Woolworths and Aldi from one schema

Input reference

FieldTypeNotes
retailersarray of coles (Coles) / woolworths (Woolworths) / aldi_au (Aldi Australia)Which retailers to search; default all three. Each runs as its own adapter with its own circuit breaker, so one retailer's bad night doesn't fail the run. Ignored in category and product mode, where the retailer is inferred from each URL, and in specialBuys mode, which always reads Aldi
modesearch / category / product / specialBuysOne mode per run; default search. specialBuys returns the products of Aldi's Special Buys drops
queriesarray of stringsSearch mode; each query runs against every selected retailer; default ["milk"]
categoryUrlsarray of URLsCategory mode; the retailer is inferred from each URL's hostname. Leave empty unless you were given a URL
productUrlsarray of URLsProduct mode; retailer inferred from each URL's hostname. Leave empty unless you were given a URL
maxItemsintegerHard cap on rows pushed across all retailers, 1 or more; default 60
excludeMarketplacebooleanWoolworths only: leave out Everyday Market (third-party marketplace) products from search and category results; default off, so results match the Woolworths site
colesProductDetailsbooleanColes only: look up each product's barcode (ean) in search and category mode; default off. Off, Coles rows have an empty ean and join on matchKey, as Aldi rows do, and a run gets far more Coles products within Coles' limit of about 80 requests. On, it costs one extra request per product, so a run returns about 75 Coles products. Product URLs always include it
specialBuysDropsarray of dates, YYYY-MM-DDSpecial Buys mode: which drops to read, as dates Aldi's Special Buys page lists; up to 20. Empty (the default) reads every drop dated today or later (Sydney date). A date Aldi's Special Buys page does not list is skipped and named in RUN_SUMMARY under perRetailer.aldi_au.specialBuys

No store-selection input in v0.1: Coles prices are as shown to a visitor with no store selected, Woolworths prices are for whichever store the logged-out session is assigned, and Aldi prices are as shown to a visitor with no store selected.

The Actor keeps to the paths each site's robots.txt allows, as those files read on 28 Sep 2026. A Coles category or product URL whose data route robots.txt disallows (for example a category ending in on-special) is refused: nothing is requested or charged for it, and it is listed in the run's RUN_SUMMARY under perRetailer.coles.refusedUrls. Special Buys mode reads only Aldi's /special-buys pages, which robots.txt allows.

Repeated category or product URLs in one run are fetched once (counted under perRetailer.<retailer>.duplicateUrls). A category or search listing is read up to 50 pages; if the retailer has more, the listing is named under perRetailer.<retailer>.truncatedListings, so you can split it into smaller categories.

Output field reference

One row per product per retailer, same shape for all three.

FieldTypeNotes
retailerstringcoles / woolworths / aldi_au
retailerProductIdstringThe retailer's own id (Coles product id, Woolworths Stockcode, Aldi SKU)
eanarray of stringsCheck-digit-validated GTIN-13 strings; empty where the retailer exposes none (Aldi), and on Coles search and category rows unless colesProductDetails is on
matchKeystringNormalised brand + name + pack size. The join key when ean is empty, and the recommended way to match the same product across retailers
namestringProduct name as shown on site
brandstring or nullOwn-label rows carry the retailer's name
packSizestring or nulle.g. 2L, 1L
pricenumberAUD, current shelf price
wasPricenumber or nullPrevious price when a reduction is shown
unitPriceobject or null{ "value": 2.98, "measure": "l" }
loyaltyPricenumber or nullAlways null for Coles and Woolworths in v0.1 (no public loyalty price)
promotionTextstring or nulle.g. Pick any 2 for $5, 25% Off, 1/2 Price; on Aldi Special Buys rows, the on-sale line, e.g. On Sale Wed 07 Oct or While Stocks Last
promotionEndsAtdate or nullAlways null in v0.1: none of the three retailers publishes an end date in the data the Actor reads
inStockboolean or nullnull where the retailer does not report stock online
categoryPatharray of stringse.g. ["Dairy, Eggs & Fridge", "Milk"]
urlstringProduct page
imageUrlstring or nullLargest image available
ratingobject or null{ "value": 4.6, "count": 212 }; always null for Coles in v0.1
currencystringAUD
marketstringau
storeIdstring or nullColes: 7674 (anonymous default). Woolworths: the assigned session's store, usually 1101 (the Actor tries up to two fresh sessions to get it); sometimes a regional store, which changes the range. Aldi: G452 (as shown to a visitor with no store selected)
onSaleDatedate or nullYYYY-MM-DD, the date the product goes (or went) on sale where Aldi gives one: on Special Buys rows, the drop date; a few other Aldi rows carry one too. null otherwise, and always null for Coles and Woolworths
scrapedAtstringISO 8601, UTC

Pricing

Pay per event; platform usage is included in that price, so this is everything you pay:

  • $0.005 start fee per run at the default 512 MB of memory (Apify charges it per GB, so a run given 2 GB pays it twice) — same as the UK listing's start fee
  • $2.00 per 1,000 products returned ($0.002 each) on the Free plan — lower on higher Apify plans

Worked example. A run searching 5 terms across all three retailers that returns 300 products costs 300 × $0.002 + $0.005 = $0.605.

Cap spend with Apify's maximum-charge setting on the run, and/or with the maxItems input.

The pricing table also lists two basket events (basket-line, basket-line-live). They belong to a basket endpoint that isn't available yet; batch runs (search, category, product and Special Buys) never charge them.

Limitations

  • Coles and Woolworths product ranges differ by store; products not ranged or priced at the store this Actor uses are skipped rather than returned as $0 rows.
  • Woolworths rows are priced at the store Woolworths assigns: usually 1101 (national default), after up to two fresh sessions when the first is assigned another store; sometimes a regional store, which changes the range; see storeId and the run's status message. Coles prices are as shown to a visitor with no store selected (store 7674). Store selection is not offered in v0.1.
  • Aldi publishes no barcode for any product and no online stock; Aldi rows join on matchKey instead of ean.
  • Special Buys mode reads the drops Aldi's Special Buys page lists at the time of the run, usually one to two weeks ahead; an earlier drop that page no longer lists cannot be read. Special Buys are sold while stocks last: rows have no end date and no stock level.
  • Public, logged-out data only: no login, basket or account data.
  • Prices can change during the day; treat scrapedAt as the price's timestamp.
  • If a retailer's site blocks a run, that retailer's run stops cleanly rather than returning bad rows.
  • Coles answers about 80 requests per run. After that, Coles stops for the rest of the run, as it does when the site blocks: the rows already returned stay, and nothing more is charged for Coles. With colesProductDetails off (the default), each request returns a page of up to 48 products, so a run can return up to a few thousand Coles products (as many as maxItems allows), with an empty ean and a join on matchKey. With it on, each Coles product costs one request, so a run returns about 75 Coles products, with barcodes.

FAQ

Is there a Coles API for prices? No. Coles does not publish one; this Coles price scraper is the nearest thing, in search, category and product mode. Turn on colesProductDetails for a barcode on nearly every row.

Is there a Woolworths API for prices? No. This Woolworths price scraper returns a GTIN-13 barcode on nearly every row, unit price where Woolworths publishes one, and current specials.

Does it include Aldi Australia prices? Yes, in search, category and product mode, exactly as Aldi publishes them online, as shown to a visitor with no store selected (service point G452): no barcode, so join on matchKey instead of ean.

Does it include Aldi Special Buys? Yes: Special Buys mode (mode: "specialBuys") returns the products of the Special Buys drops Aldi lists, by default every drop dated today or later, with each drop's date in onSaleDate.

Why do Aldi rows have no EAN? Aldi does not publish a barcode anywhere in its listing API, product API or product pages. Aldi rows carry an empty ean array and a matchKey (normalised name and pack size) instead.

Can I build a supermarket price comparison across Coles, Woolworths and Aldi? Yes. Match rows on ean (Coles and Woolworths) or matchKey (all three, and the fallback for Aldi) to build an Australian grocery price comparison in one schema.

Which store's prices does this use? Coles: the price shown to a visitor with no store selected (store 7674). Woolworths: whichever store the logged-out session is assigned, usually 1101; sometimes a regional store, which changes the range; see storeId. Aldi: as shown to a visitor with no store selected (service point G452). None is user-selectable in v0.1.

How do I limit what I spend? Set Apify's maximum-charge cap on the run, and/or set maxItems to cap the number of rows returned.

How fresh is the data? Every row is scraped live during the run; scrapedAt records when. Prices can move during the day, so treat each row as a snapshot.

Does this use my Coles or Woolworths account? No. The Actor only reads public, logged-out product data — no login, basket or account information.

How reliable is this? If a retailer's site blocks a run, that retailer stops cleanly for the rest of the run rather than returning bad rows. A scheduled canary run of the default input (all three retailers, milk, 60 items) runs every day; of its 21 scheduled runs from 26 Sep to 16 Oct 2026, all 21 finished successfully and returned 60 rows, 20 from each retailer. In 4 of the 21 (before 0.1.13, which retries for 1101), Woolworths priced the rows at a regional store (3221) instead of the national default 1101; every row records its storeId.

Barcode coverage and run-success figures for this Actor are on the data-quality page: https://data.yappman.com/data-quality

Ratings and reviews

Ratings and reviews on the Store page help other buyers judge whether this Actor fits their use, whatever your experience.

Changelog

See the Changelog tab on this Actor's page for version history.

Read more

Need something custom?

I build and maintain Actors for retail pricing, property listings and sites behind Akamai or Cloudflare, plus scheduled data pipelines with monitoring. Fixed-scope work through Abley-Yapp Consulting — email info@yappman.com with the site and the fields you need.