Coles AU Scraper - Groceries, Prices & Reviews avatar

Coles AU Scraper - Groceries, Prices & Reviews

Pricing

from $1.20 / 1,000 product results

Go to Apify Store
Coles AU Scraper - Groceries, Prices & Reviews

Coles AU Scraper - Groceries, Prices & Reviews

Scrape Coles.com.au grocery products and customer reviews. Search by keyword, browse categories, or use product/search URLs. Returns name, brand, price, was price, unit price, size, specials, availability, aisle/category, nutrition, allergens, ingredients, ratings, and reviews.

Pricing

from $1.20 / 1,000 product results

Rating

5.0

(1)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

3

Bookmarked

33

Total users

6

Monthly active users

2.8 hours

Issues response

3 days ago

Last modified

Share

Coles Scraper: Grocery Prices, Specials, Nutrition & Reviews

Coles Scraper turns the Coles Australia online grocery store into structured product data. Search by keyword, browse whole categories, pull the On Special catalogue, or paste product and listing links. Every product comes back as one flat record with price, was price and savings, unit price, size, availability, category data, nutrition, ingredients, allergens and, optionally, customer ratings and reviews. Export to JSON, CSV or Excel, or read the results through the API.

Why This Scraper?

  • Two input types, one filter surface. Search keywords, browse category slugs, or combine both, then apply the same price, rating and specials filters either way. Paste product, search, category or On Special links when you already have them.
  • Specials done properly. Pull the storefront's On Special catalogue by type (half price, multi buy, online only), or run a complete sweep that also catches genuinely reduced products the curated On Special listing itself misses.
  • Was price and savings, worked out correctly. Strike through price, saving amount and percent, promo label and, for multi buy offers, the structured deal detail, all read straight off each product's own pricing data.
  • Unit price that is actually usable. Comparable price recovered even when Coles' own structured unit price field is empty, always paired with the basis it is quoted against so a per gram value is never mistaken for a per kilogram one.
  • Full grocery labelling. Long description, ingredients, allergens, dietary statement, storage instructions, dimensions, country of origin, GTIN, nutrition panel and images when detail collection is switched on.
  • Ratings and reviews on demand. The aggregate rating and star distribution come with basic detail collection; the full review list, with star rating, text, author, date and helpful count, is a separate switch.
  • Built for monitoring. Resume one interrupted run from its previous dataset, or turn on incremental mode so a daily schedule returns only new, updated and reappeared products instead of a full snapshot every time.

Use Cases

  • Price tracking and comparison sites: collect current price, was price, unit price and specials across categories to power a grocery comparison tool.
  • Deal and specials alerting: monitor the On Special catalogue and specific departments, and get notified only when something changes.
  • Nutrition and ingredient research: build datasets of allergens, dietary claims and nutrition panels across a category for dietary or health apps.
  • Market and assortment research: track category depth, brand presence and product variants across Coles' catalogue over time.
  • Customer sentiment analysis: pull ratings and review text for the products that carry them to understand what shoppers say.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
productId"8150288"
name / title"Coles Full Cream Milk 3L" / "Coles Full Cream Milk 3L"
brand / size"Coles" / "3L"
price / wasPrice3.1 / 6.2
savingsAmount / savingsPercent3.1 / 50
promoLabel / promotionType / specialType"1/2 Price" / "SPECIAL" / "PERCENT_OFF"
comparablePrice / unitPrice / unitOfMeasure"$1.03/ 1L" / 1.03 / "l"
isOnSpecial / isOnlineOnlytrue / false
isAvailable / availabilityTypetrue / "InStoreAndOnline"
aisle / category / department"Full Cream Milk" / "Milk" / "DAIRY"
departments["dairy-eggs-fridge"]
imageColes product image link
longDescription"A fresh Australian full cream milk, rich and creamy."
ingredients / allergens"Full cream milk." / "Contains Milk"
nutritionserving size and the full nutrition breakdown, when published
gtin / barcode"9300601123456" / same value (alias)
breadcrumbs["Dairy", "Milk", "Fresh Milk"] (category, sub-category, aisle)
inStock / stockStatustrue / "in_stock" (or "out_of_stock"); mirrors isAvailable
countryOfOrigin"Australia"
rating / reviewCount4.6 / 128
ratingDistribution{ "5": 96, "4": 20, "3": 7, "2": 3, "1": 2 }
reviewsstar rating, title, text, author, date, helpful count (when enabled)
urlColes link to the product page

Fields added for cross-site parity: barcode (same value as gtin), breadcrumbs (category, sub-category, aisle), inStock and stockStatus (mirror isAvailable). They are additive and never count as a change in incremental mode.

Category, department and specials records carry the same underlying product fields; a variant matrix and category breadcrumb are added once product detail is switched on.

How to Use

  1. Pick an input type: search or browse with keywords and category slugs, or paste product, search, category and On Special links.
  2. Add filters: price range, minimum rating, specials category or exclusions, department exclusions.
  3. Switch on Fetch product details and Fetch customer reviews if you need the full label and reviews, and set Max products to control run size and cost.
  4. Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.

Search for a keyword inside a category:

{
"inputMode": "search",
"queries": ["milk"],
"categories": ["dairy-eggs-fridge"],
"fetchDetails": true,
"maxItems": 20
}

Half price specials, skipping one department:

{
"inputMode": "search",
"specialsCategory": "halfprice",
"excludeCategories": ["liquorland"],
"maxItems": 50
}

A complete sweep of everything currently reduced:

{
"inputMode": "search",
"specialsCategory": "allspecials-complete",
"maxItems": 200
}

Paste a product link and a category link, with reviews:

{
"inputMode": "url",
"urls": [
"https://www.coles.com.au/product/coles-full-cream-milk-3l-8150288",
"https://www.coles.com.au/browse/dairy-eggs-fridge/milk"
],
"fetchReviews": true
}

In url mode every one of these Coles link shapes is accepted (the www. prefix is optional, and tracking parameters such as utm_source are ignored):

LinkExample
Product page (slug and id)/product/coles-full-cream-milk-3l-8150288
Product page, shared with tracking/product/coles-full-cream-milk-3l-8150288?utm_source=share
Product page by id only/product/8150288
Product page without www.https://coles.com.au/product/...
Bare numeric product id8150288
Search results/search/products?q=milk
Search results (short form)/search?q=milk
Search results from a page/search/products?q=milk&page=2
Search results, sorted/search/products?q=milk&sort=priceAscending
Category/browse/dairy-eggs-fridge
Sub-category/browse/dairy-eggs-fridge/milk
Category from a page/browse/dairy-eggs-fridge?page=2
Category, sorted/browse/dairy-eggs-fridge?sort=priceAscending
On Special, all/on-special
On Special from a page/on-special?page=2
On Special by department/on-special/dairy-eggs-fridge
On Special, half price/on-special?filter_Special=halfprice

The half-price filter is applied only on On Special links; on a category link it is ignored (the run logs a note and collects the whole category), so paste /on-special/<department>?filter_Special=halfprice instead. page= starts that listing on that page; sort= accepts the site's own priceAscending / priceDescending values, the short forms priceAsc / priceDesc, or name.

Behaviour change: urls is no longer empty by default. In url mode, if you leave the URLs field untouched, the run now scrapes one example of each supported link shape (seven example links, one per distinct target) instead of returning nothing. Set your own links, or lower Max products, to control the run. The default input mode is search, so runs that do not select url are not affected: outside url mode the example links are ignored and do not change the incremental state key, so existing scheduled search and category runs keep their saved baseline.

Output views

The dataset has four ready-made tables in the Console Output tab:

  • Products: price, was price, savings, promo label, unit price, size, specials flags, departments and rating, one row per product.
  • Product detail: GTIN and barcode, category path, ingredients, allergens, dietary statement, nutrition, storage, country of origin and long description.
  • Reviews: one row per review, with the product, its total review count, and each review's star rating, title, text, author, date, verified-purchase flag and helpful votes.
  • Changes (incremental mode): change type, changed fields, price, was price and first/last seen times.

A run summary (counts of products returned, enriched, scanned and excluded) is also saved as the OUTPUT record in the run's key-value store.

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/coles-au-scraper").call(run_input={"inputMode": "search", "queries": ["milk"]})
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
print(product["name"], product.get("price"))

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/coles-au-scraper').call({ inputMode: 'search', queries: ['milk'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Resume and recurring updates

  • Resume (resumeFromRunId) continues one specific interrupted run: paste its run or dataset id and this run skips every product id already in that dataset, so it returns only the remaining new products and you don't pay twice.
  • Incremental mode (incrementalMode) is for a schedule against the same search. The first run returns everything as NEW; later runs return only NEW, UPDATED (with changedFields) and REAPPEARED products, while unchanged ones are suppressed and not billed unless emitUnchanged is on. EXPIRED products (no longer found) are only produced once a run has scanned the whole tracked search, not when a cap or Resume cut it short, and only with emitExpired on. stateKey names or shares the stored state; leave it empty and the actor derives one automatically from your search and filter setup. ignoreFieldsForChanges lists field names (or dotted nested paths such as a.b) that must not count as a change: they are still returned in every row but never turn a product into UPDATED. For example, ["promoLabel"] stops a changed promo label alone from re-reporting a product. Ratings, review counts and the parity fields above are always ignored.

Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape; the Apify dataset is never changed.

What gets written to the connector: for Notion, one page per product with its key fields and a short summary. For other connectors, a best effort write of the same condensed summary. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify โ†’ Settings โ†’ Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where products should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
inputModeselect(none, prefilled search)search to use keywords, categories and filters, or url for pasted links and product ids.
modestring (hidden)searchLegacy compatibility field for saved tasks and API integrations made before inputMode. New runs should use inputMode.
queriesarray(none, prefilled ["milk"])Keywords to search for. Leave empty to browse the selected categories in full.
categoriesarray(none, prefilled ["dairy-eggs-fridge"])Category slugs (the part after /browse/ in a Coles category URL). With keywords, they limit where the search looks; without keywords, their full listings are returned.
specialsCategoryselect"" (not selected)Add products from Coles' On Special catalogue: all specials, a complete sweep of everything reduced, half price, multi buy, or online only.
urlsarrayseven example links, one per distinct targetColes product, search, category or On Special URLs, or bare numeric product ids (url mode). A page= number starts that listing on that page; sort= (priceAscending / priceDescending, the short forms priceAsc / priceDesc, or name) orders that URL's results. If you select URL mode without editing this field, the run scrapes one example of each supported link shape (product page, search, category, sub-category, On Special all / department / half-price), so set maxItems or your own links.
sortByselectrelevanceOrder applied to the collected products: relevance, price_asc, price_desc, or name. Coles itself only serves relevance order; the others are applied after collection.
minRatingselect"0"Keep only products rated at least 3, 4 or 5 stars. Requires product detail or review collection; products with no reviews are excluded when this is set.
specialsOnlybooleanfalseKeep only products currently showing a special price or offer.
excludeSpecialsCategoriesarray (select)(none)Drop products in these specials categories instead of collecting and paying to enrich them. Excluding allspecials drops every on-special product.
excludeCategoriesarray(none)Departments to skip entirely, so they are never collected or charged. A product is skipped if it belongs to any listed department, even if it also appears under one you keep.
minPriceinteger(none)Only keep products priced at or above this amount (AUD).
maxPriceinteger(none)Only keep products priced at or below this amount (AUD).
fetchDetailsbooleantrueCollect each product's full detail (description, ingredients, allergens, dietary statement, storage, dimensions, country of origin, GTIN, nutrition panel, images) plus its aggregate rating.
fetchReviewsbooleanfalseAlso collect customer reviews for each product. Most Coles grocery products carry no reviews; those records leave the rating and review fields absent.
maxReviewsPerProductinteger20Cap on reviews collected per product when fetchReviews is on. Cost guard: review collection per product is always bounded, with a maximum of 200 per product (0 or a larger value is treated as 200), so a single product can never produce an unbounded review run. Lower it to keep runs smaller.
maxItemsinteger20Maximum number of products to return across the whole run. Use 0 for unlimited.
maxPagesinteger(none, all pages)Maximum result pages per keyword, category or URL. Does not cap the number of products; maxItems does that.
resumeFromRunIdstring(none)Id of a previous run (or dataset) of this actor. Products already in that dataset are skipped, so this run returns only new products.
incrementalModebooleanfalseTurn on for daily or recurring monitoring: returns only new, updated and reappeared products on repeated runs over the same search.
stateKeystring(none)Name this monitoring campaign to keep its state stable, or share state across differently configured runs. Auto-derived from your search and filter settings when left empty.
emitUnchangedbooleanfalseIncremental mode only. Also return (and bill) products unchanged since the last run.
emitExpiredbooleanfalseIncremental mode only. Also return (and bill) products no longer found, once a run has fully scanned the tracked search.
ignoreFieldsForChangesarray[]Incremental mode only. Field names (or dotted paths) that never count as a change. They are still returned in every row.
proxyobject{ "useApifyProxy": true }Connection settings.
mcpConnectorsarray(none)Optional: send a summary of each product to apps you authorized under Integrations.
notionParentPageUrlstring(none)Notion connector only: page under which product pages are created.
maxNotifyListingsinteger50Cap on items written to each connector per run. Does not affect the dataset.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"productId": "8150288",
"name": "Coles Full Cream Milk 3L",
"title": "Coles Full Cream Milk 3L",
"brand": "Coles",
"description": "COLES FULL CREAM MILK 3L",
"size": "3L",
"url": "https://www.coles.com.au/product/coles-full-cream-milk-3l-8150288",
"price": 4.5,
"isOnSpecial": false,
"comparablePrice": "$1.50/ 1L",
"unitPrice": 1.5,
"unitOfMeasure": "l",
"unitMeasure": "1l",
"currency": "AUD",
"isAvailable": true,
"availabilityType": "InStoreAndOnline",
"aisle": "Full Cream Milk",
"category": "Milk",
"subCategory": "Dairy, Eggs & Fridge",
"department": "DAIRY",
"departments": ["dairy-eggs-fridge"],
"isOnlineOnly": false,
"image": "https://cdn.productimages.coles.com.au/productimages/1/8150288.jpg",
"longDescription": "A fresh Australian full cream milk, rich and creamy.",
"gtin": "9300601123456",
"brandSlug": "coles",
"countryOfOrigin": "Australia",
"countryOfOriginStatement": "Made in Australia from at least 99% Australian ingredients",
"categoryPath": ["Milk", "Dairy, Eggs & Fridge", "Full Cream Milk"],
"ingredients": "Full cream milk.",
"allergens": "Contains Milk",
"dietary": "Source of Calcium",
"storageInstructions": "Keep refrigerated. Store at or below 5 degrees C.",
"nutrition": { "servingSize": "250mL", "servingsPerPackage": "12.00", "breakdown": [{ "name": "Energy", "perServe": "450kJ", "per100": "180kJ" }] },
"rating": 4.6,
"ratingCount": 128,
"reviewCount": 128,
"ratingDistribution": { "5": 96, "4": 20, "3": 7, "2": 3, "1": 2 },
"recommendedCount": 118,
"reviews": [
{
"reviewId": "1000000001",
"rating": 5.0,
"title": "Family favourite",
"body": "Fresh and creamy, our family buys it every week.",
"author": "sampleShopper",
"date": "2025-02-14T06:01:00.000+00:00",
"verifiedPurchase": true,
"isRecommended": true,
"helpfulCount": 4
}
],
"reviewsCollected": 1,
"searchMode": "search"
}

Plan Requirement

The default connection setting works on a standard (datacenter) connection, but Coles' protection intermittently refuses individual connections: roughly one request in two to three is answered with a short "Request unsuccessful" page instead of the product page. The actor detects that page, treats it as a refusal rather than an empty result, and retries on a fresh connection, so a normal run still completes. If refusals persist, it switches to a residential connection, then to a built-in backup connection. For large or frequent runs, pinning the residential proxy group under Connection gives more consistent access and fewer retries.

An Apify free plan does not include proxy access. If your plan denies the proxy connection and the backup connection cannot reach the store either, the run stops with this message: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required: https://apify.com/pricing. If you entered your own proxy URLs, check that their credentials are valid." If the store itself is down, the run reports that Coles' website is offline instead of a connection problem.

FAQ

How much does it cost?

You pay per product returned, plus a detail enrichment charge per product when product details and/or reviews are collected, plus a per-run start fee. The Pricing tab shows the current rates. Use Max products to cap the cost of any run.

This actor collects only publicly available product data. You are responsible for how you use it: follow Coles' terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Prices and product facts are generally not protected, but images and some descriptions may be subject to third party rights.

Can I get only new or changed products on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared products, classified against the previous run of the same search, and unchanged ones are not billed unless you turn that on too.

Why does a GTIN show as scientific notation in Excel or Google Sheets?

This is an import display issue, not a data problem: the dataset itself always stores gtin as text. Excel and Google Sheets both auto-detect long all-digit columns as numbers on a plain CSV import and re-render them in scientific notation, losing trailing digits. Import through Data โ†’ From Text/CSV (Excel) or choose "Do not convert" (Google Sheets), and set the gtin column to Text; the JSON and Excel dataset downloads are not affected.

Why did my run fail instead of returning an empty dataset?

The run is marked failed only when it could never establish a working connection to the store at all, when the Resume id you supplied is not a readable run or dataset from your account, or when the resume and incremental mode inputs conflict (for example, incremental mode already has saved state for this search and you also supplied Resume). A run that connects successfully but finds no matching products, or where your filters and exclusions removed everything collected, completes normally with an empty dataset and a status message explaining why.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

๐Ÿ”— Want more grocery data?

Pair this actor with these related scrapers from the same team:

๐Ÿฅฆ Woolworths AU Scraper
Scrape Woolworths Australia (woolworths.com.au) grocery products and reviews. Search by...
๐Ÿฅฆ ALDI AU Scraper
Scrape ALDI Australia (aldi.com.au) products: name, brand, price, was-price, savings...
๐Ÿฅฆ Carrefour Spain Scraper
Scrape Carrefour Spain (carrefour.es) products. Search by keyword, browse a category, or...
๐Ÿฅฆ REWE.de Scraper
Scrape REWE Germany (rewe.de) grocery products: current price, was-price and discount...
๐Ÿฅฆ Auchan France Scraper
Scrape Auchan.fr products: grocery, drinks, household and general merchandise. Real price...
๐Ÿท Dan Murphyโ€™s Scraper
Scrape Dan Murphyโ€™s products by category, keyword, or specials. Extract 45+ fields...

๐Ÿ‘‰ Browse all abotapi scrapers

๐Ÿ’ฌ Support

  • ๐Ÿž Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • ๐Ÿ› ๏ธ Need another site, extra fields or a private build? Email contact@abotapi.com.
  • โญ Enjoying it? A quick review on the actor page helps other users find it.