Bunnings Scraper - Products, Reviews & Q&A
Pricing
from $1.50 / 1,000 product results
Bunnings Scraper - Products, Reviews & Q&A
Scrape bunnings.com.au products with full specifications, price, brand, stock, image gallery, warranty, customer reviews, rating stats and Q&A. Search by keyword with brand, price, rating and sort filters, or paste product / category / search URLs.
Pricing
from $1.50 / 1,000 product results
Rating
5.0
(1)
Developer
Abot API
Maintained by CommunityActor stats
2
Bookmarked
9
Total users
2
Monthly active users
11 hours ago
Last modified
Categories
Share
Bunnings Scraper: Hardware & Home Improvement Products, Specs and Reviews
Bunnings Scraper turns Bunnings Warehouse, Australia's largest hardware and home improvement retailer, into structured product data you can use anywhere. Search by keyword with brand, price, rating and product-offer filters, or paste product, category and search URLs, and get one clean record per product with full specifications, pricing, image galleries, warranty text, and the site's own customer reviews with rating statistics. Run once for a snapshot, resume an interrupted run without paying twice, or schedule it and get only what changed, then export the results into your apps or pull them through the API.
Why This Scraper?
- Two ways to collect. Search by keyword with brand, price, rating and product-offer filters, or paste any product, category or search URL directly.
- Full product detail. Specifications, warranty text, dimensions, payment options and the complete image gallery, fetched by default (a pasted product URL always fetches these regardless of the setting).
- Customer reviews at scale. Review text, star rating, author, date and aggregate rating statistics, with a cap you control per product.
- Built for schedules. Incremental mode returns only new and changed products on recurring runs, and a product that disappears can be marked EXPIRED once a run has scanned the whole tracked search.
- Resume without paying twice. Continue one interrupted run from a previous run or dataset ID, and the actor also recovers automatically after a platform restart.
- Honest pricing signals. Was-price and discount fields are never invented. They stay empty unless the site itself publishes a real reduced price.
- Send data straight into your apps. Pipe results into Notion, Linear, Airtable or Apify through MCP connectors, no code required.
Use Cases
- Price and catalogue monitoring: track prices, stock and promotions on drills, mowers, paints and fasteners over time.
- Competitor and market research: benchmark hardware retail pricing and product ranges by brand or category.
- Marketplace and comparison sites: source specifications, images, warranty text and pricing to list Bunnings products elsewhere.
- Review and sentiment analysis: pull customer reviews and rating distributions for power tools, appliances or building materials.
- Sourcing and procurement: build a structured feed of products, brands and specifications for trade or DIY audiences.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
code / itemNumber | "0299323" / "0299323" |
name / title | "XU1 18V Brushless Drill Driver Kit" / "Ozito XU1 18V Brushless Drill Driver Kit" |
brand / brandUrl | "Ozito" / brand page URL |
url | canonical product page link |
price / currency / formattedPrice | 49.98 / "AUD" / "$49.98" |
priceType / priceAvailable | "FROM" / true |
wasPrice / savingsAmount / savingsPercent / isOnSpecial | null / null / null / false |
offerTypes / isRedemptionOffer | ["Redemption Offer"] / true (site's own product-offer tag) |
promotion / hasPromotion | campaign name, dates, loyalty-exclusive flag / true |
paymentOptions | instalment options such as pay-later or card split plans |
rating / ratingCount | 4.5 / 120 |
reviews[] | review text, star rating, author, date, recommended flag, helpful votes |
reviewStats | aggregate rating stats plus star distribution |
specifications | flattened spec name to value map |
features[] | full feature list (name, code, value) |
warranty | warranty and returns text |
weight / dimension | packaged and product weight and dimensions |
images[] / imageUrl | full image gallery and primary image |
variants | size / colour variant matrix with per-variant code and URL |
categories / categoryPath | category taxonomy |
fulfilment | delivery and click-and-collect availability |
searchMode / source | "search" or "url" / "bunnings.com.au" |
Was-price and discount fields (wasPrice, savingsAmount, savingsPercent, isOnSpecial) stay empty on almost every product: Bunnings runs an everyday-low-price model and publishes no strike-through, "was" or RRP price anywhere in its product data, on the listing card or the product page. These fields are kept for a consistent schema and populate only if the site itself ever exposes a genuine reduced price, never estimated or fabricated from other numbers. In incremental mode, every record also carries changeType, changedFields, firstSeenAt and lastSeenAt (see "Resume and recurring updates" below).
How to Use
- Pick a mode:
search(keyword plus filters) orurl(paste product, category or search links). - Fill in the fields for that mode: keywords and filters for search, or the list of URLs for url mode.
- Fetch product details is on by default and adds a small per-product charge; turn it off to skip it for search or category results (a pasted product URL always includes it regardless). Turn on Fetch customer reviews too if you want reviews (also a small per-product charge).
- Set Max products to control run size and cost, then click Start.
Search by keyword with filters:
{"mode": "search","queries": ["cordless drill", "exterior paint"],"brand": "Ryobi","sortBy": "ratingDesc","minPrice": 20,"maxPrice": 500,"minRating": 4,"fetchDetails": true,"maxItems": 50}
Paste a category page and a product page:
{"mode": "url","urls": ["https://www.bunnings.com.au/our-range/tools/power-tools/drills","https://www.bunnings.com.au/ryobi-18v-one-drill-driver-starter-kit-r18dd22_p0715241"],"fetchDetails": true,"fetchReviews": true,"maxReviewsPerProduct": 50}
Only products carrying the site's redemption-offer tag:
{"mode": "search","queries": ["cordless drill"],"productOffers": "redemption-offer","maxItems": 100}
Recurring monitoring of a search, changes only:
{"mode": "search","queries": ["exterior paint"],"incrementalMode": true,"emitExpired": true,"stateKey": "exterior-paint-watch"}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/bunnings-com-au-scraper").call(run_input={"mode": "search","queries": ["cordless drill"],"fetchDetails": True,"maxItems": 50,})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/bunnings-com-au-scraper').call({mode: 'search',queries: ['cordless drill'],fetchDetails: true,maxItems: 50,});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 interrupted run: paste its run or dataset ID and the actor skips every product already collected there, so you don't pay twice. Max products then counts only the new products. - Incremental mode (
incrementalMode) is for scheduled runs over the same search. Each product is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on), orEXPIRED(only produced after a run that scanned the whole tracked search with no Max products or Max pages cap hit and no Resume used, and only whenemitExpiredis on). A product that comes back after an earlier run had already marked it EXPIRED is then classifiedREAPPEARED, notNEW, and keeps its original first-seen date. Without a prior complete run that emitted EXPIRED, nothing is ever classified REAPPEARED. stateKeynames or shares the stored state. Left empty, state is scoped automatically to your exact mode, keywords or URLs, filters, sort order, and detail/review settings, so two differently configured runs never mix baselines. With incremental mode off, output is exactly as before.- The aggregate
rating,ratingCount,reviewsandreviewStatsfields are driven by other customers and change far more often than the product's own catalogue data, so they are excluded from change detection (still fully returned) rather than flagging almost every recurring run as updated. maxPagescaps the number of result pages walked per keyword or URL, not an absolute page number: a pasted URL that already names a start page (for examplepage=5) walks forward from there. Use0to walk every page; the run still stops once Max products is reached, a page repeats, or the store's own listed total is reached.
Send results into your apps (MCP connectors)
Optionally pipe the scraped products 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 product, not the full JSON. Each product 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 product pages 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 plus filters) or url (paste product, category or search links). |
queries | array | none (prefill: ["cordless drill"]) | Search keywords, one or more (search mode). |
urls | array | none (prefill: ["https://www.bunnings.com.au/search/products?q=hammer"]) | Product, category or search URLs to scrape (url mode). |
brand | string | none | Keep only products whose brand contains this text. |
sortBy | string | relevance | relevance, priceAsc, priceDesc, ratingDesc, reviewsDesc, or nameAsc. |
minPrice | integer | none | Keep only products priced at or above this amount (AUD). |
maxPrice | integer | none | Keep only products priced at or below this amount (AUD). |
minRating | integer | none | Keep only products with an average rating at or above this value (1 to 5). |
productOffers | string | any | Keep only products carrying the site's own product-offer tag: redemption-offer or new-arrival. |
fetchDetails | boolean | true | Open each product page for full specifications, warranty, dimensions, gallery and price detail. |
fetchReviews | boolean | false | Also collect customer reviews and aggregate rating statistics per product. |
maxReviewsPerProduct | integer | 20 | Cap on reviews collected per product when reviews are on. Use 0 for all available. |
maxItems | integer | 20 | Maximum number of products to return across the whole run. Use 0 for unlimited. |
maxPages | integer | 0 | Safety cap on result pages walked per keyword or URL. 0 walks every page. |
resumeFromRunId | string | none | Previous run or dataset ID to continue from (returns only products not already collected there). |
incrementalMode | boolean | false | Turn on for scheduled runs of the same search to get only new and changed products. |
stateKey | string | none | Optional name for an incremental-mode monitoring campaign, or to share state deliberately. |
emitUnchanged | boolean | false | Also return (and bill) products unchanged since the last run, marked UNCHANGED. |
emitExpired | boolean | false | Also return (and bill) products no longer found, marked EXPIRED, only after a complete scan. |
proxy | object | residential connection pinned to Australia | Connection settings for reaching the store. |
mcpConnectors | array | none | Optional: send a summary of each product to apps you authorized under Integrations. |
notionParentPageUrl | string | none | Notion connector only: page under which product pages are created. |
maxNotifyListings | integer | 50 | Cap 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.
{"code": "0299323","itemNumber": "0299323","name": "XU1 18V Brushless Drill Driver Kit","title": "Ozito XU1 18V Brushless Drill Driver Kit","brand": "Ozito","brandUrl": "https://www.bunnings.com.au/our-range/tools/ozito","url": "https://www.bunnings.com.au/xu1-18v-brushless-drill-driver-kit_p0299323","price": 49.98,"currency": "AUD","formattedPrice": "$49.98","priceType": "FROM","wasPrice": null,"savingsAmount": null,"savingsPercent": null,"isOnSpecial": false,"offerTypes": ["Redemption Offer"],"isRedemptionOffer": true,"promotion": { "campaign": "AU_TOOLS_FREE_DELIVERY", "startDate": "2026-09-01", "endDate": "2026-10-01", "onePassExclusive": false },"hasPromotion": true,"rating": 4.5,"ratingCount": 120,"reviews": [{ "rating": 5, "title": "Great value", "author": "SampleUser", "date": "2026-08-15T00:00:00", "body": "Sample review text.", "recommended": true, "helpfulVotes": 4, "notHelpfulVotes": 0, "verifiedPurchaser": true }],"reviewStats": { "averageRating": 4.5, "reviewCount": 120, "ratingDistribution": { "5": 80, "4": 25, "3": 10, "2": 3, "1": 2 } },"specifications": { "Voltage": "18V", "Battery included": "Yes" },"features": [{ "name": "Voltage", "code": "voltage", "value": "18V" }],"warranty": "3 year warranty on tool, 1 year on battery.","weight": "1.6kg","dimension": "35cm x 25cm x 10cm","images": ["https://www.bunnings.com.au/images/sample-1.jpg", "https://www.bunnings.com.au/images/sample-2.jpg"],"imageUrl": "https://www.bunnings.com.au/images/sample-1.jpg","variants": [{ "code": "0299324", "itemNumber": "0299324", "url": "https://www.bunnings.com.au/sample-variant_p0299324", "options": [{ "name": "Colour", "value": "Blue" }] }],"categories": ["Tools", "Power Tools", "Drills"],"categoryPath": ["Tools", "Power Tools", "Drills"],"fulfilment": { "availableForDelivery": true, "inStorePickup": true },"searchMode": "search","source": "bunnings.com.au"}
Plan Requirement
The store answers reliably only to a residential connection in Australia, and the input's Connection setting defaults to exactly that, rotating to a fresh exit automatically on any refusal. An account without residential proxy access in Australia will exhaust its fallback connections and the run fails with a clear message rather than completing empty. Larger or more frequent runs benefit from your own plan's proxy allowance.
FAQ
How much does it cost?
You are billed for the results you actually collect: a charge per product returned, plus a charge for detail fetching, which is on by default (turn it off to skip it, except for a pasted product URL which always includes it), and an optional charge if you turn on review fetching. The Pricing tab on the actor page shows the current rates. Use Max products to cap the cost of any run.
Is it legal to scrape Bunnings?
This actor collects only publicly available product data from bunnings.com.au. You are responsible for how you use it: follow Bunnings' 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 photos, logos 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 and updated products, and unchanged ones are suppressed and not billed unless you also turn on Emit unchanged.
Why are the was-price and discount fields always empty?
Bunnings runs an everyday-low-price model and publishes no strike-through, "was" or RRP price anywhere in its product data, not on the listing card and not on the product page. wasPrice, savingsAmount and savingsPercent are kept for a consistent schema and populate only if the site itself ever exposes a genuine reduced price; they are never estimated or fabricated from other numbers.
Why did my run fail instead of returning an empty dataset?
If every connection attempt is refused before any product data can be read, for example because the account has no access to a residential connection in Australia, the run fails with an actionable message instead of completing with zero results. A single refused request during a normal run is retried automatically on a fresh exit and does not fail the run. The run also fails if a pasted resumeFromRunId cannot be read, or if Incremental mode is combined with resumeFromRunId on a search that already has saved state.
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... | ๐ BIG W Marketplace Scraper Scrape BIG W Marketplace seller listings from bigw.com.au: name, brand, price, was-price... |
| ๐ Costco AU Scraper Scrape Costco.com.au products with full details and customer reviews. Search by keyword... | ๐ Officeworks Scraper Scrape Officeworks products by keyword, category, or URL. Extract names, brands, prices... |
| ๐ Harvey Norman Scraper Scrape Harvey Norman Australia products: name, brand, price, was-price / discount... | ๐ Chemist Warehouse AU Scrape chemistwarehouse.com.au products with prices, RRP, discounts, stock, images... |
๐ Browse all abotapi scrapers
๐ฌ Support & custom scrapers
- ๐ 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 abotapi@proton.me or message Telegram @abotapi.
- โญ Enjoying it? A quick review on the actor page helps other users find it.