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
17
Total users
4
Monthly active users
19 days ago
Last modified
Categories
Security
Limited permissionsShare
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" |
The Output tab offers four views of the same dataset: Products (overview), Product detail (specifications, gallery, warranty, stock), Customer reviews (one row per review, when reviews are fetched) and Changes since the last run (incremental mode).
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/products/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. - What is compared.
UPDATEDis decided by a product's own catalogue data (price, was-price and savings, specials and offer types, promotion/campaign, stock and fulfilment, name, brand, images, categories);changedFieldslists exactly what moved. Customerrating,ratingCount,reviews,reviewStatsand thescrapedAttimestamp are always excluded from the comparison (they are still returned), so a new review alone never makes a productUPDATED. UseignoreFieldsForChangesto exclude more fields, for exampleimageUrl; a bare name matches that field at any depth and a dotted path such aspromotion.startDatematches one exact place. 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.
Supported URL shapes
The Bunnings URLs field defaults to one example of each distinct shape below, except the accepted variants marked below, which are not in the default because they resolve to the same results as the plain link (the same product pasted in several forms is always collected once). Links are processed in order until Max products is reached, so with the default of 20 only the first link (the hammer search) is scraped and charged; raise Max products, or paste only the links you want, to reach the others. Only products actually collected are charged. Likewise a search-mode run with the keywords field untouched now searches "cordless drill". Replace the lists to scrape your own.
| Shape | Example |
|---|---|
| Search results | https://www.bunnings.com.au/search/products?q=hammer |
| Search, later page | https://www.bunnings.com.au/search/products?q=hammer&page=2 |
| Category, leaf | https://www.bunnings.com.au/products/tools/power-tools/drills |
| Category, top level | https://www.bunnings.com.au/products/tools |
| Category, later page | https://www.bunnings.com.au/products/tools/power-tools/drills?page=2 |
| Category with product-offers filter | https://www.bunnings.com.au/products/tools/power-tools/drills?productoffers=New%20Arrival |
| Search with product-offers filter | https://www.bunnings.com.au/search/products?q=drill&productoffers=New%20Arrival |
| Product page | https://www.bunnings.com.au/ryobi-18v-one-drill-driver-starter-kit-r18dd22_p0715241 |
| Search, sorted (accepted variant, not in the default; the site returns the same order, so the sort is ignored) | https://www.bunnings.com.au/search/products?q=hammer&sort=price_asc |
| Product page, without www (accepted variant, not in the default) | https://bunnings.com.au/ryobi-18v-one-drill-driver-starter-kit-r18dd22_p0715241 |
| Product page with tracking query (accepted variant, not in the default) | https://www.bunnings.com.au/ryobi-18v-one-drill-driver-starter-kit-r18dd22_p0715241?utm_source=share |
Legacy /our-range/... links and bare /p<id> links are not served by the site; they are skipped with a warning in the run log. The sort parameter in a pasted URL is ignored because the site does not reorder results for it; use the Sort input. A link with a product-offers filter is applied by the site on both search and category pages; when the filter leaves nothing (for example the hammer search has no New Arrival products), the run log says no products matched that filter instead of staying silent. A category or search link the site no longer serves is reported in the log with its own warning and is never treated as a complete, empty listing.
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 | ["cordless drill"] | Search keywords, one or more (search mode). |
urls | array | one example per supported link shape (see the table below) | 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. If nothing carries the tag for your keyword, the run log says so. |
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; capped at 1000 reviews per product. |
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. |
ignoreFieldsForChanges | array | none | Incremental mode only: field names that must not count as a change (still returned in the output). |
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
A residential connection in Australia is required. Bunnings sits behind a managed browser challenge: datacenter connections are refused with a "Just a moment..." interstitial (HTTP 403), while a residential Australian exit gets the real pages (HTTP 200). The input's Connection setting therefore defaults to residential, pinned to Australia, and rotates to a fresh exit automatically on any refusal. Datacenter proxies will not work.
An account without residential proxy access (for example an Apify free plan) sees this warning in the run log and the run continues on a backup connection:
The selected connection is unavailable to this run.Apify free plans do not include residential proxies.Continuing on a backup connection; some pages may still be unavailable.For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs.
If a backup connection serves data, the log notes Served over the backup connection (the default connection was unavailable). If no page can be read at all, the run fails with one of these messages instead of finishing empty:
- Proxy refused for the account:
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. - Residential unavailable and backup failed:
No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Bunnings pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again. - Requests failed:
Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later.
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:
| ๐ Harvey Norman Scraper Scrape Harvey Norman Australia products: name, brand, price, was-price / discount... | ๐ 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 by keyword or product, search and category URLs. Extract... | ๐ Amazon Australia Product & Reviews Scraper Scrape Amazon Australia (amazon.com.au) products and customer reviews. Search by keyword... |
| ๐ Chemist Warehouse AU Scrape chemistwarehouse.com.au products with prices, RRP, discounts, stock, images... | ๐ Appliances Online Scraper Scrape appliancesonline.com.au by category, keyword, or URL. Extract title, brand, AUD... |
๐ 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.