Coles scraper in Python: Coles Australia prices API for grocery prices, half-price specials, unit prices and barcodes to JSON/CSV
A short tutorial for pulling Coles Australia (coles.com.au) grocery prices into Python with the Coles Scraper actor on Apify. Search by keyword or barcode, scrape whole categories, or grab the weekly specials catalogue (half price, multibuy, online only). Every product comes back with price, was price, saving, unit price, special type, stock and category path, and optionally barcode (GTIN), ingredients, allergens and the nutrition panel. Useful for price monitoring, specials trackers, FMCG competitor pricing and Australian grocery price comparison.
Disclosure: I built this actor; it's a paid tool on Apify ($1.50 per 1,000 results). The code in this repo is MIT-licensed.
coles.com.au is a Next.js site sitting behind Imperva bot protection. Each search, category and product page has a matching JSON data route; the actor calls those directly over plain HTTP (no headless browser), through Australian residential proxies, and rotates to a fresh session whenever Coles pushes back. In test runs a full half-price catalogue (1,549 products) finished in under a minute with 0 failed requests.
pip install apify-clientfrom apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("rel8ble/coles-scraper").call(run_input={
"specials": "halfprice", # or "all", "multibuy", "onlineonly"
"searchQueries": ["coffee"],
"maxItems": 50, # per source; 0 = everything
})
for p in client.dataset(run["defaultDatasetId"]).iterate_items():
print(p["brand"], p["name"], p["size"], p["price"], p["wasPrice"], p["unitPriceText"])example.py is the runnable version: it writes this week's half-price list to coles_halfprice.csv (biggest dollar saving first), then searches a few keywords and prints the cheapest products per 100 g / per litre.
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('rel8ble/coles-scraper').call({
searchQueries: ['9300617064923'], includeDetails: true, maxItems: 1, // barcode lookup
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((p) => `${p.name} $${p.price} ${p.nutrition?.per100?.Energy}`));| Field | Default | What it does |
|---|---|---|
searchQueries |
- | Keywords as typed into the Coles search box ("milk", "tim tam"); a barcode works too |
categories |
- | Category slugs or browse URLs ("bakery", "pantry/breakfast"); "all" = whole catalogue (~35,000 products) |
specials |
none |
all, halfprice, multibuy or onlineonly; new specials start each Wednesday |
startUrls |
- | Any coles.com.au search, category, specials or product URL (filters kept) |
maxItems |
100 | Products per source; 0 = everything |
includeDetails |
false | Adds barcode, ingredients, allergens, nutrition, origin, images (one extra request per product) |
storeId |
online store | A store number like 7799 for that store's prices and stock |
includeSponsored |
false | Include paid product ads (flagged isSponsored) |
A search result with includeDetails: true (trimmed):
{
"productId": "2351720",
"name": "Dairy Milk Hazelnut Chocolate Block",
"brand": "Cadbury",
"size": "180g",
"url": "https://www.coles.com.au/product/cadbury-dairy-milk-hazelnut-chocolate-block-180g-2351720",
"price": 5.5,
"wasPrice": 8,
"saveAmount": 2.5,
"discountPercent": 31,
"unitPrice": 3.06,
"unitPriceText": "$3.06/ 100g",
"currency": "AUD",
"isOnSpecial": true,
"specialType": "price_drop",
"offerDescription": "save $2.50",
"available": true,
"availableQuantity": 877,
"department": "Chips, Chocolates & Snacks",
"category": "Chocolates",
"aisle": "Chocolate Blocks",
"source": "search",
"sourceQuery": "chocolate",
"barcode": "9300617064923",
"countryOfOrigin": "Australia",
"nutrition": {
"servingSize": "25g",
"per100": { "Energy": "2340 kJ", "Protein": "9.0 g", "Fat - Total": "36.2 g", "Sugars - Total": "46.4 g" }
}
}Half-price rows from the specials list, same run:
[
{ "brand": "Coca-Cola", "name": "Zero Sugar Soft Drink Bottle", "size": "1.25L", "price": 2.25, "wasPrice": 4.5, "unitPriceText": "$1.80/ 1L", "specialType": "half_price" },
{ "brand": "I&J", "name": "Frozen Raw Prawns Tail Off", "size": "500g", "price": 12, "wasPrice": 24, "unitPriceText": "$24.00/ 1kg", "specialType": "half_price" },
{ "brand": "Twinings", "name": "English Breakfast Tea Bags 100 Pack", "size": "200g", "price": 6.75, "wasPrice": 13.5, "unitPriceText": "$0.07/ 1ea", "specialType": "half_price" }
]specialType is one of half_price, price_drop, multibuy, percent_off or special.
$1.50 per 1,000 results (pay per product saved; product details included at no extra charge). 1,000 products = $1.50, the full half-price list (~1,500) ≈ $2.30. Failed requests and retries are never charged. Apify's free plan includes $5 of monthly credit.
- Prices are the online store's unless you set
storeId; in-store prices can differ by store. - Coles' own listing totals are approximate (a category saying 550 may return 549 or 551); duplicates are removed.
includeDetailsroughly doubles run time; leave it off when you only need prices.- Fresh produce and in-store bakery items have no barcode; customer reviews aren't included.
- Collects public product and price data only. You're responsible for using it in line with Coles' terms and applicable law.
- Actor on the Apify Store: https://apify.com/rel8ble/coles-scraper
- Apify Python client docs: https://docs.apify.com/api/client/python
- More of my scrapers: https://apify.com/rel8ble
MIT