Costco AU Scraper - Products, Prices & Reviews
Pricing
from $1.00 / 1,000 product results
Costco AU Scraper - Products, Prices & Reviews
Scrape Costco.com.au products by keyword or product, search and category URLs. Extract prices, brands, ratings, review counts and text, stock, images, specifications, promotions and full product details in clean structured data.
Pricing
from $1.00 / 1,000 product results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
3 days ago
Last modified
Categories
Share
Costco Australia Scraper: Products, Prices & Customer Reviews
Costco Australia Scraper turns costco.com.au into a clean product data feed. Search by keyword with brand, category, rating and price filters, or paste product, search, category and specials links directly. Every match comes back as one flat record with current and original "was" price, savings amount and percent, per-unit price, brand, rating, stock, images, specifications and promotions, plus the full customer reviews on demand. Browse the Hot Buys, Last Chance and New arrivals collections directly, then export to JSON, CSV or Excel, or pull results straight into your app through the API.
Why This Scraper?
- Two ways in. Search by keyword with brand, category, rating and price filters, or paste product, search, category and specials links directly, no need to build URLs by hand.
- Specials collections, browsable. Hot Buys, Last Chance (clearance) and New arrivals are their own views: pick one with a single input, or paste the collection link.
- Real discount math, not a guess. Every discounted product carries the original "was" price, the savings amount and percent, and the discount's start/end dates, alongside a per-unit price with its actual basis (kg, litre, 100 g and more) rather than a bare dollar figure.
- Membership-gated prices handled honestly. costco.com.au hides the price on some grocery lines behind a membership login; those records still come back with every other field populated and
priceHidden: true, with no price where the site withholds one, rather than a guessed number. - Detail and reviews on demand. Switch on full product detail (description, ingredients, warranty, returns, category path, full image gallery) and customer reviews (rating, title, author, date, text, helpful votes, plus aggregate rating stats) per run, and pay only for what you use.
- Built for monitoring. Incremental mode returns only new, changed, reappeared and expired products on a recurring search; Resume continues one interrupted crawl without re-collecting or re-charging what a previous run already has.
- 7 sort orders, 4 filters. Relevance, price, name and rating-based sort orders, plus brand, category, minimum rating and price band filters, applied before any per-product enrichment runs.
Use Cases
- Price and specials monitoring: track the Hot Buys, Last Chance and New arrivals collections, or a saved search, on a schedule and get back only the products that are new, repriced or gone.
- Retail and pricing intelligence: compare Costco Australia's warehouse pricing, unit prices and savings against other retailers for a category or brand.
- Catalogue and merchandising research: pull specifications, categories, images and rating distributions for range planning, comparison tools or content.
- Review and sentiment analysis: collect full customer reviews and aggregate rating statistics for a product line or brand.
- Deal-hunting apps and newsletters: surface currently discounted products (
isOnSpecial,savingsPercent) for a shopping tool or content feed.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
code | "500123" |
name / title | "Sample Stainless Steel Blender" / "Northfield Sample Stainless Steel Blender" |
brand | "Northfield" (needs Fetch product details; null on some generic products with no brand) |
price / priceFormatted | 79.99 / "$79.99" |
wasPrice / wasPriceFormatted, savingsAmount / savingsPercent | 99.99 / "$99.99", 20.00 / 20 |
isOnSpecial | true |
discountStartDate / discountEndDate | "2026-03-01T14:00:00.000Z" / "2026-03-21T13:59:59.999Z" |
unitPrice / unitPriceFormatted | 2.50 / "$2.50" (grocery/household lines only) |
unitOfMeasure / unitMeasure | "kg" / "1kg" |
priceHidden / membershipRequired | false / false (member-gated lines return priceHidden: true, usually with price: null) |
currency | "AUD" |
averageRating / numberOfReviews | 4.6 / 128 |
stockStatus / stockLevel | "inStock" / 42 |
inStock, priceStatus, priceHiddenReason | true, "visible" or "hidden", "membership_required" |
slug, categoryCode, parentId, depth | product slug and category tree position |
shortDescription, delivery, businessDelivery, inRestrictedZone | summary and delivery details the site publishes; inRestrictedZone is the site's own restricted-zone flag, passed through unchanged |
attributes | the product's feature rows as a name-to-value object (brand, size, origin and so on) |
ingredients, allergens, nutrition, nutritionText, storageInstructions, importantNotice, warnings | read from the product page's own ingredient, allergen, storage, Nutrition Facts, notice and warning sections; filled only for products that publish them (mostly food, supplement and alcohol lines), and need Fetch product details on. nutrition is the structured panel (servings, serving size, rows with a per-serving and a 100 g value); nutritionText is the same panel as one line |
currentPrice, regularPrice, discountPrice, unitPriceLabel | price helpers; discountPrice only on specials |
categories / breadcrumbs, specs | ["Kitchen", "Small Appliances"], [{ "name": "Colour", "value": "Silver" }] |
images | ["https://www.costco.com.au/medias/sample-500123-1.jpg"] |
url, hasVariants | "https://www.costco.com.au/.../p/500123", false |
promotions | [] (filled only when the site publishes promotion text) |
reviews | [{ "rating": 5, "title": "Great value", "author": "SampleShopper", "body": "..." }] (when enabled) |
reviewStats | { "averageRating": 4.6, "totalReviews": 128, "ratingDistribution": { "5": 90, "4": 30 } } |
brand, title (brand plus name), categories, breadcrumbs, specs, description and the full image gallery come from the product detail, so they need Fetch product details on (the default). Every record also carries englishName, searchMode (whether search or url mode found it), departmentNumber, maxOrderQuantity / minOrderQuantity (with details on), requiresAgeVerification, warehouseSavings and couponDiscount (extra warehouse or coupon markdowns on top of the listed price), and reviewCount (reviews actually collected this run, capped by Max reviews per product). With Incremental mode on, every record also carries changeType, changedFields, firstSeenAt and lastSeenAt.
How to Use
- Pick a mode:
search(keyword and filters) orurl(paste product, search, category or specials links). - In search mode, add a keyword, or pick a Specials / offers collection, brand, category or minimum rating to narrow it; the price band filter applies in both modes.
- In url mode, each link gets an equal share of Max products (unused share rolls on to the next link), so leaving the links field unedited scrapes a small sample of every supported link type (search, product, category, specials, facet search, paged search and API links) instead of nothing; replace them with your own links. The untouched list has 12 links and starts with the three product links (two product pages and one API product link), so each of those always returns its own product, followed by the search, category, specials and API list links. At the default Max products of 20 all 12 links contribute (one or two products each); at 12 every link contributes exactly one; below 12 the links are served in list order until the cap is reached, so at 6 only the first six links return a product.
- Turn on Fetch product details and/or Fetch customer reviews for the fields you need, and set Max products or Max pages per search to control run size and cost.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Search a keyword with filters:
{"mode": "search","queries": ["blender"],"sortBy": "top_rated","minRating": "4","fetchDetails": true,"maxItems": 50}
Browse a specials collection:
{"mode": "search","specialsCategory": "hot_buys","brand": "Northfield","fetchDetails": true,"maxItems": 100}
Paste product and specials links:
{"mode": "url","urls": ["https://www.costco.com.au/sample-product/p/500123","https://www.costco.com.au/hot-buys"],"fetchReviews": true,"maxReviewsPerProduct": 20}
Recurring monitoring with incremental mode:
{"mode": "search","queries": ["olive oil"],"maxItems": 0,"incrementalMode": true,"emitExpired": true,"stateKey": "olive-oil-watch"}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/costco-au-scraper").call(run_input={"mode": "search", "queries": ["blender"]})for product in client.dataset(run["defaultDatasetId"]).iterate_items():print(product["name"], product["price"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/costco-au-scraper').call({ mode: 'search', queries: ['blender'] });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Membership-gated prices
costco.com.au requires a paid membership to see prices on some products, mostly grocery and household lines. This actor does not log in and does not hold a membership; it reads the storefront's own public product feed exactly as the site serves it to a visitor, so a member-gated line comes back with priceHidden: true and, where the site withholds the number, price: null, while every other field (name, images, category, rating, specs) is still populated. membershipRequired repeats the site's own membership-restriction flag, so it can stay false or empty on a line whose price is hidden for another reason. Most catalogue items publish a public price and are unaffected.
Two things to know:
priceHiddenandmembershipRequiredcome from search and category results. A product reached through a pasted product link (.../p/<code>) returns them empty.- A product with no visible price never passes a Minimum price or Maximum price filter. With either filter set, pasted product links are skipped too, so leave the price filter empty when you paste individual products.
Specials collections and the "was" price
Costco Australia groups its promotions into three named collections: Hot Buys (current member savings), Last Chance (clearance) and New arrivals. Pick one with Specials / offers in search mode, or paste the collection link (for example https://www.costco.com.au/hot-buys/c/hot-buys, /c/last-chance or /c/new; the short /hot-buys, /last-chance and /new forms work too) in URL mode; a keyword, brand or category can still narrow a specials view. Every discounted product keeps its current price and adds the original wasPrice, savingsAmount, savingsPercent and the discount's discountStartDate / discountEndDate. A product that is not reduced returns isOnSpecial: false and wasPrice: null so the dataset stays consistent; the site publishes no separate promo badge text, so none is invented.
Unit price basis
Some grocery and household lines carry a per-unit price. The site names the basis only as a two letter code next to the number; unitOfMeasure and unitMeasure expand it into a readable, arithmetic verified form (kg becomes 1kg, mL becomes 100mL, and so on). Always read unitPrice together with unitMeasure: a unit price on an mL product usually refers to 100 mL, not a single mL. A small number of lines use a code outside the known table; those come back verbatim with unitMeasure: null rather than a guessed quantity.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted run: paste its run or dataset ID and the actor skips every product it already collected there, so you don't pay twice. - Incremental mode (
incrementalMode) is for scheduled runs over the same search or URL. Each product is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEARED, orEXPIRED(only after a run that walked every page of every search/URL to its natural end, and only withemitExpiredon; a run that stopped at Max products or Max pages per search, or one continuing a Resume, never marks anything expired that run). - Set Max products to
0for monitoring (hard ceiling of 100000 products per run). With a cap, each result page only checks as many products as the cap still allows, and the rest of that page is skipped. Their changes (a new price, a product coming back) are not reported that run, and the run still finishes normally without a warning. They show up on the first run that reaches them. A new customer review by itself never flips a product toUPDATEDor re-bills the review add-on; a genuine change to the product's own rating still does. State is kept separately per distinct combination of mode, search/URL, sort, brand, category, filters and detail/review settings; use State key to name a monitoring campaign or to deliberately share state across runs.
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: a condensed, human readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items 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
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (keyword and filters) or url (paste links). |
queries | array | (none) | Search keywords (search mode), for example laptop. Each is searched separately. |
sortBy | string | relevance | relevance, price_asc, price_desc, name_asc, name_desc, best_selling (alias top_sellers), or top_rated. |
specialsCategory | string | (none) | Limit to a specials collection: hot_buys, last_chance, or new. Combine with a keyword, brand or category to narrow. |
brand | string | (none) | Limit to a single brand, exact spelling (search mode). |
category | string | (none) | Limit to a category code, for example cos_9 (search mode). |
categoryCode | string | (none) | Same as category, and also accepts a pasted category page link. |
parentId | string | (none) | Browse everything under a parent category code (its children and deeper levels). |
filters | array | (none) | Site facet filters as FacetName:FacetValue, for example Brand:Apple. Values are case-sensitive and must match the site's own facet spelling; a value the site does not list returns no products. |
rawQuery | string | (none) | Advanced: a raw storefront query expression (text:sort:facet:value) used as-is instead of the keyword, sort, category and filter inputs. |
productCode | string | (none) | Fetch one product by its numeric code (for example 126124) or the full product page link ending in /p/<code> (runs in url mode). A page slug on its own is rejected with a message. |
minRating | string | 0 | Keep only products rated at least this many stars: 0, 3, 4, or 5. |
urls | array | one example of each supported link type | Product, search, category or specials URLs to scrape (url mode). Search links can carry a facet token (q=) or a start page (page=). If left unedited in url mode, each link gets an equal share of Max products, so a sample of every link type is scraped. |
minPrice | integer | (none) | Keep only products priced at or above this amount (AUD). Narrows search results and pasted search/category links; drops hidden-price products and pasted product links. |
maxPrice | integer | (none) | Keep only products priced at or below this amount (AUD). Same scope as minPrice. |
fetchDetails | boolean | true | Fetch each product's full detail (description, ingredients, warranty, returns, images, category path). |
fetchReviews | boolean | false | Also collect customer reviews and aggregate rating stats. |
maxReviewsPerProduct | integer | 20 | Cap on reviews collected per product (0 = the hard ceiling of 1000). |
maxItems | integer | 20 | Maximum products for the whole run (0 = the hard ceiling of 100000 products). |
maxPages | integer | 0 | Cap on result pages walked per keyword/URL (0 = every page the site has). |
resumeFromRunId | string | (none) | Continue one interrupted run; paste its run or dataset ID. |
incrementalMode | boolean | false | Return only new, changed and reappeared products on a recurring search. |
stateKey | string | (none) | Name or share an incremental-mode monitoring campaign. |
emitUnchanged | boolean | false | Also return (and bill) unchanged products. |
emitExpired | boolean | false | Also return (and bill) products no longer found, once a run has fully scanned the tracked search. |
ignoreFieldsForChanges | array | [] | Incremental mode only. Fields that must not trigger UPDATED or appear in changedFields; top-level names (promotions) or dotted nested paths (specs.value). The fields stay in the output. Saved state is re-checked with your current list, so editing it causes no one-off wave of UPDATED rows. |
proxy | object | Apify Proxy | Connection settings. |
mcpConnectors | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which records are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"code": "500123","name": "Sample Stainless Steel Blender","title": "Northfield Sample Stainless Steel Blender","englishName": "Sample Stainless Steel Blender","url": "https://www.costco.com.au/kitchen/sample-stainless-steel-blender/p/500123","brand": "Northfield","price": 79.99,"priceFormatted": "$79.99","currency": "AUD","priceHidden": false,"membershipRequired": false,"wasPrice": 99.99,"wasPriceFormatted": "$99.99","savingsAmount": 20.00,"savingsPercent": 20,"isOnSpecial": true,"discountStartDate": "2026-03-01T14:00:00.000Z","discountEndDate": "2026-03-21T13:59:59.999Z","unitPrice": null,"unitPriceFormatted": null,"unitOfMeasure": null,"unitMeasure": null,"warehouseSavings": false,"couponDiscount": null,"averageRating": 4.6,"numberOfReviews": 128,"categories": ["Kitchen", "Small Appliances"],"breadcrumbs": ["Kitchen", "Small Appliances"],"specs": [{ "name": "Colour", "value": "Silver" }],"images": ["https://www.costco.com.au/medias/sample-500123-1.jpg"],"stockStatus": "inStock","hasVariants": false,"reviews": [{"reviewId": "1","rating": 5,"title": "Great value","author": "SampleShopper","body": "Works well and easy to clean.","reviewDate": "2026-02-14","helpfulVotes": 3}],"reviewCount": 1,"reviewStats": {"averageRating": 4.6,"totalReviews": 128,"ratingDistribution": { "5": 90, "4": 30 }}}
Plan Requirement
The default connection is the Apify datacenter proxy, and it was measured to work: the product JSON API answered on a datacenter connection with no block observed. Residential was not tested. If the site starts refusing requests the run adapts automatically and moves to a residential connection; for large or frequent runs, choosing the residential proxy group under Connection gives more headroom. Repeated "Connection refused" lines in the log mean the site was blocking.
FAQ
How much does it cost?
You pay a small per-run start fee, plus a per-product fee for every result returned. Fetching full product detail and collecting customer reviews are separate, optional add-ons, billed only when you turn them on, with the review add-on charged per review collected. Both add-ons are charged per product as each result is delivered (the detail add-on once per product with full detail, the review add-on once per review delivered), never as a lump at the end of the run, and never for unchanged products suppressed by Incremental mode. The Pricing tab shows the current rates. Use Max products to cap the cost of any run.
Is it legal to scrape Costco Australia?
This actor collects only publicly available product and customer review data shown on costco.com.au. You are responsible for how you use it: follow Costco's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product names, prices and specifications are generally facts, but product images and review text 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, and unchanged ones are not billed unless you turn on Emit unchanged.
Why does a product come back with price: null?
A small number of grocery and household lines on costco.com.au hide the price from non-members. This actor does not hold a membership and does not log in; it reports what the public storefront returns, so those records come back with price: null and priceHidden: true, with every other field (name, images, category, rating) still populated, rather than a guessed price. membershipRequired is true when the site itself flags the line as members only.
Why did my run return nothing instead of an error?
When nothing is collected, the run ends as succeeded with a "No products matched" status message instead of failing. That covers a search or URL with no matches, filters that exclude everything (including a price filter on pasted product links), a Resume where every product was already collected, and a run where the site refused every request. The status message is the same in all of these cases, so the run log is where you tell them apart: repeated "Connection refused" lines mean the site was blocking, and running again later usually helps. Otherwise, try a broader keyword, relax the filters, or double check the URLs you pasted. If a monitoring tool needs a hard signal, alert on a run with zero results. A bad Resume from a previous run ID is different: that stops the run with an explicit error before anything is collected or charged.
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 e-commerce data?
Pair this actor with these related scrapers from the same team:
| 🛒 Target AU Scraper Scrape products and customer reviews from Target.com.au. Search by keyword or use... | 🥦 ALDI AU Scraper Scrape ALDI Australia (aldi.com.au) products: name, brand, price, was-price, savings... |
| 🥦 Woolworths AU Scraper Scrape Woolworths Australia (woolworths.com.au) grocery products and reviews. Search by... | 🛒 Kmart Scraper Scrape products and customer reviews from Kmart.com.au. Search by keyword or use... |
| 🛒 Harvey Norman Scraper Scrape Harvey Norman Australia products: name, brand, price, was-price / discount... | 🛒 Amazon Australia Product & Reviews Scraper Scrape Amazon Australia (amazon.com.au) products and customer reviews. Search by keyword... |
💬 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.