Coles Australia Scraper - Prices, Specials, Barcodes avatar

Coles Australia Scraper - Prices, Specials, Barcodes

Pricing

from $0.50 / 1,000 product rows

Go to Apify Store
Coles Australia Scraper - Prices, Specials, Barcodes

Coles Australia Scraper - Prices, Specials, Barcodes

Watch Coles Australia prices at one real store and get back only what moved: price cuts, stock, promotions, unit price. Or scrape outright by keyword, aisle or specials. Pin any run to a store by postcode, suburb or store id, because Coles prices are not national. Barcode and nutrition on request.

Pricing

from $0.50 / 1,000 product rows

Rating

0.0

(0)

Developer

SR

SR

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Coles Australia Scraper

Pull live product data out of the Coles Australia grocery catalogue at a real store: name, brand, pack size, current price in Australian dollars, the price before the promotion, unit price, stock, image and the product's own barcode. Search by keyword, browse any aisle, take the whole specials catalogue in one run, or read a full product record including ingredients, allergens, nutrition panel and country of origin.

Coles prices are not national. Give this actor a postcode, a suburb or a store id and every row comes back priced at that shop, with the store stamped on it. That matters more than it sounds: see below.

Or watch instead of scraping. Name a watchlist, schedule the run, and from the second run on you get back only the products whose price, stock, promotion or unit price moved at that shop, with what they used to cost alongside what they cost now.

No account, no cookies to paste, no browser to babysit. Give it a search term and it returns rows.

What you get

FieldWhat it holds
product_idColes' own id. Stable, and the key you join runs on
name, brand, size"Full Cream Milk", "Coles", "3L"
priceCurrent price in AUD. Null, never zero, when Coles publishes none
was_pricePrice before the promotion. Null when nothing is on promotion
save_amount, save_percent, save_statementThe saving, three ways Coles states it
is_on_special, promotion_type, multi_buy_promotionWhat kind of deal is running
unit_price, unit_measure, unit_price_label$1.65, 1L, "$1.65/ 1L"
is_available, availability_type, available_quantityWhether Coles will actually sell it to you
is_sponsoredTrue when Coles served the row as a paid placement
retail_limit, promotional_limit, is_age_restrictedPurchase limits
department, category, aisleWhere it sits in the shop
variations_totalHow many variants of the product Coles lists
image, urlImage and product page
store_id, store_name, store_suburb, store_state, store_postcodeWhich shop these prices were read at
is_store_pricedFalse means the row is a national catalogue figure, not a shelf price

With Add barcode, ingredients and nutrition switched on, every row also carries gtin, ingredients, allergen_statement, dietary_claims, nutrition, storage_instructions, pack_dimensions, country_of_origin, country_of_origin_statement, long_description, min_guarantee and last_updated.

The four things it does

Search by keyword. One or more terms, each run separately, each row recording which term found it. "milk" returns 146 products, "chocolate" returns 670, and the actor pages through them 48 at a time until it reaches your limit.

Browse a category. A whole department, dairy-eggs-fridge, or one aisle inside it, dairy-eggs-fridge/milk. The milk aisle holds 197 products. Top levels include fruit-vegetables, meat-seafood, bakery, deli, pantry, frozen, drinks, chips-chocolates-snacks, health-beauty, cleaning-laundry, baby, pet and home-garden. A path that does not exist is reported as such rather than quietly returning a different aisle.

Product detail by id or URL. Paste product ids, or paste product URLs and the id gets read off the end of them. This is the operation that returns the barcode and the nutrition panel, neither of which appears in a listing row.

Everything on special. The current promotions catalogue, 7.591 products at the time of writing, paged the same way as a search.

You can narrow a search or a browse to one kind of offer: half price, multi buy or online only. It is applied by Coles rather than by filtering after the fact, so it is a genuine narrowing. "chocolate" returns 670 products with no filter and 77 with half price on.

Prices differ by store, and that is the point

Measured on one afternoon, same product ids, same two-minute window, only the store changed:

ProductSydneyDarwinKarratha WA
Tim Tam Original 200g$3.00, was $6.00$3.00, was $6.30$3.00, was $6.42
Bananas, loose$4.90/kg$4.90/kg$4.50/kg
a2 Full Cream UHT 1L$3.90$4.05$4.17
Coles Full Cream Milk 3L$4.95not sold$4.95
White sliced bread$4.60$4.60$4.60, and not sold in Burnie TAS

The range moves further than the prices do, and store format moves it most. A search for "milk" returned 128 products in one Victorian supermarket, 121 in Karratha, 118 in Broken Hill, 110 in Darwin and 84 at a small-format Coles Central in the Sydney CBD. The specials catalogue ran from 2.567 products at that express store to 7.066 in Broken Hill.

So a promotion tracker that ignores the store will report a markdown that is not running in half the country, and a price comparison will quote a figure nobody is charged.

Leave the store empty and you get Coles' national catalogue instead. That is a real thing and sometimes what you want, but it is not a shelf price: the national listing for "milk" is 146 products, larger than every store measured, and the national specials catalogue is 7.591 against 2.567 to 7.066 in real shops. Runs with no store say so in the summary and every row carries is_store_priced: false, so it is never something you find out later.

A store that cannot be found stops the run. It does not quietly fall back to national figures, because handing you national prices under a store label would be exactly the kind of confident wrong answer the rest of this page is about.

If you have been told that store-specific Coles pricing cannot be pinned from a scraper, that Coles resolves it from where the request comes from and there is no way to override it: that is not true, and the table above is what overriding it looks like.

Watch mode: only what moved, at the shop you buy from

Turn on Watch for changes, give the watchlist a name, and schedule the run. From the second run on you get back only the products that moved, with what they used to cost sitting next to what they cost now.

The comparison is done at your store. That matters more here than anywhere else on this page: a price change in a national catalogue is a change to a figure nobody is charged, while a price change at the shop you actually buy from is the thing you wanted to know. Same for promotions, which run in some states and not others, and for range, because a product can be dropped from your store while the national listing still carries it.

Five kinds of change, each with its own flag

A row that changed because the product went out of stock is a different alert from a price cut, and one merged changed flag makes both of them useless. So every row says which dimensions moved, and you can pick which ones count:

DimensionWhat it catchesOn by default
priceWhat you pay movedyes
availabilityIn stock, out of stock, or the price withdrawn entirelyyes
promotionA multi-buy or half-price week starting or endingyes
unit_priceThe price per kg or per litre movedyes
was_priceThe advertised saving moved while the price heldno

Two of those are worth spelling out, because a price-only watcher misses both.

A promotion can start without the price moving. "2 for $8" leaves the shelf price exactly where it was. Anything watching price alone reports UNCHANGED for the entire promotion.

A pack can shrink instead of getting dearer. 3L at $4.95 becomes 2.5L at $4.95 and price is identical, while unit_price goes from $1.65/L to $1.98/L. That is the whole event, and it only shows up if something is watching the unit price.

Each row carries price_changed, availability_changed, promotion_changed, unit_price_changed and was_price_changed separately, a changes list of everything that moved, and one change_type headline for the biggest of them. Stock outranks price in that headline, because a price on something you cannot buy is not a price.

The first run tells you it is the first run

A watchlist with no history cannot know whether anything changed. It has not measured "no changes", it has measured nothing, and those are different.

So a first run returns every row marked change_type: BASELINE with is_change: false, and the summary reports changesDetected: null rather than 0. "Only return rows that changed" is ignored on that run, on purpose, so you can see the watchlist matched the products you meant before you schedule it. The summary says all of this in words.

Returning everything labelled NEW would fire an alert for every product you already knew about on day one. Returning nothing would leave you a successful run with an empty dataset and no way to tell it from a breakage. Neither is worth the ten rows it saves.

What it refuses to tell you

It will not compare two different stores. A baseline captured at one store against a run at another would report almost every product as changed, and every one of those alerts would be wrong. The watchlist records its store and refuses the comparison, then starts again at the store this run used, and says so.

It will not report a withdrawn product as free. Coles answers a product it has stopped selling with a complete record and no price at all. Against a baseline of $4.95 that is a 100% markdown to anyone who subtracts, and "milk now free" arriving as a price alert is the worst thing this feature could do. A price comparison here needs a real number on both sides: a price disappearing is reported as PRICE_WITHDRAWN and a price reappearing as PRICE_RESTORED, both under stock rather than price, and neither ever produces a delta.

It will not call a product discontinued on a hunch. If you watch a fixed list of product ids and one stops resolving, that is DELISTED and you get told once. If you watch a search term, a product missing from this run has almost certainly moved off page one rather than out of the range, so it is counted in the summary and no alert is invented for it. A run that also hit fetch errors never claims a delisting at all.

It will not call a failed run quiet. If a run retrieves no products, the summary says the comparison could not be made. It does not say nothing changed, and it does not say your whole list was discontinued.

Where the watchlist lives

In your Apify account, under the name you gave it, created by the actor on its first run and kept indefinitely. We never hold it and cannot see what you watch. Every run also writes the same record to its own key-value store as watchlist_state, so if the saved copy is ever unreachable you can paste that back in as baseline and carry on without losing your history. The summary always names which of the two the run actually compared against.

What it deliberately does not do

It will not pretend to look products up by barcode. Coles does not index barcodes, and it does not say so. Feed its search the GTIN printed on its own milk bottle and you get fifteen products headed by a paper towel at $5.50 and a tin of dog food at $14.00. Real names, real prices, HTTP 200, no error anywhere. Any scraper that offers a barcode input against Coles without reading the flag Coles sets on that response will tell you, with total confidence, that your milk barcode is dog food. So there is no barcode-lookup operation here, because there is no barcode lookup at Coles. The barcode itself is published on each product record and is returned whenever you ask for detail, which is a different and honest thing. If you need to go from a barcode to a product, run detail over the ids you already have and match on gtin at your end.

It will not offer a sort order. Coles accepts a sort parameter and ignores it. Price ascending and price descending returned identical first rows in testing and the response kept reporting relevance ordering either way. Shipping a sort control would be shipping a button that does nothing, so there isn't one. Sort the dataset after the run instead.

The part that matters: it does not hand you a confident wrong answer

Coles has several ways of saying "no" that arrive as a successful response with products in it. Each one was found by testing for it, and each one is guarded.

A query it cannot match returns substitutes, not nothing. Search for zzzqqqxxwwv and Coles returns two products, the first being a hayfever tablet. Search for asdkjhasdkjhasd and it returns a children's matching game. These are well-formed rows with real names and real prices, and nothing about the row itself looks wrong. Coles does flag the response, and this actor reads that flag: a term that matched nothing comes back as a row with found: false and a reason, never as an unrelated product.

A product Coles no longer sells keeps its record and loses its price. Ask for a product that never existed and you get a clean "not found". Ask for one Coles has stopped selling and you get a complete record - name, brand, barcode, images

  • with the entire price object set to null. Anything that treats a missing price as zero publishes a free product. Prices here are only ever read through a helper that returns null, never zero, and the row carries is_available: false so you can filter on the fact rather than infer it from a suspicious number.

Sponsored rows repeat across pages. Coles injects paid placements on top of the 48-per-page grid, so page one of a search carries more than 48 products. Those extras are not stable between pages: three products on page two and five on page three of one test had already been returned earlier. Rows are deduplicated by product id, and every row tells you whether it was a paid placement, so you can drop them or keep them as you like.

Coles advertises a filter it then refuses. Its own response lists an "all specials" filter with a count next to it. Requesting that filter returns a 404, every time. The specials operation uses the dedicated promotions catalogue instead, which is why it works.

Every run writes a summary record saying how many products came back, how many had a price, how many were paid placements, how many are no longer available, and which of your search terms Coles could not match. If something went thin, the summary says so rather than leaving you to notice.

Input

InputMeaning
operationsearch, category, product or specials
storeA postcode, a suburb, or a Coles store id. Prices the whole run at that shop
monitor_modeoff, or changes to compare this run against the last one
watchlist_nameKeeps separate watchlists apart. One name per store and per set of products
trackWhich of price, availability, promotion, unit_price, was_price count as a change
only_changedReturn just the rows that moved. Ignored on a first run
baselineOptional. A saved watchlist_state record to compare against directly
queriesSearch terms, one per line
categoriesCategory paths such as dairy-eggs-fridge/milk
product_idsProduct ids or full product URLs
special_offerany, half_price, multi_buy or online_only
with_detailsAdds barcode, ingredients, nutrition and origin. One extra request per product
max_resultsHow many products in total. A page carries 48
max_pagesPage ceiling per term or category
retriesRe-asks for a page that did not come back

What people use it for

Price monitoring against your own range or a competitor's, at the stores you actually care about rather than at a national average nobody pays. Regional price-gap analysis: run the same basket at a metropolitan store and a remote one and the difference falls straight out. Promotion tracking, because was_price and save_percent make a half-price week visible without watching the catalogue by hand, and because the store field tells you where the markdown is actually running. Range-gap analysis: browse an aisle, compare the product ids against your own list, and the difference is the gap. Unit-price comparison across pack sizes, which unit_price and unit_measure make arithmetic rather than guesswork. Product content, because the detail operation returns the ingredients and nutrition panel Coles prints on the pack.

Prices are Coles' online prices in AUD for the store you selected. Promotions change weekly, so treat a run as a snapshot with a timestamp rather than a permanent fact.

Notes

Empty results are a successful run, not a failure: if Coles has nothing for your term, you get zero rows and a summary that explains why, not a crash. Errors carry a code and a message and land in the errors record.

This is an unofficial scraper. It is not affiliated with, endorsed by or connected to Coles Group Limited. Use the data in line with Coles' terms and with the law that applies to you.