Harvey Norman Australia Scraper - Products & Reviews
Pricing
from $1.00 / 1,000 product results
Harvey Norman Australia Scraper - Products & Reviews
Scrape Harvey Norman Australia products: name, brand, price, was-price / discount, specifications, image gallery, GTIN, department, stock, dimensions, rating and customer reviews. Search by keyword with brand, price and rating filters, or paste product / listing URLs.
Pricing
from $1.00 / 1,000 product results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
7 hours ago
Last modified
Categories
Share
Harvey Norman Australia Scraper — Products & Reviews
Extract product data from harveynorman.com.au — Australia's electrical, computer, furniture and bedding retailer. Search by keyword with filters, or paste product and listing URLs, and get one clean record per product with an optional full detail extraction that adds specifications, image gallery, department, dimensions and customer reviews.
What you can collect
- Identity — canonical title, name, brand, SKU, product id, GTIN, product URL
- Pricing — current price, was / original price, discount amount and percent,
an
isOnSpecialflag, currency and the promotion label - Specials — scrape the store-wide Super Deals or Clearance collections directly, or paste any sale listing URL
- Ratings — average rating and review count on every product
- Detail (optional) — full specifications, image gallery, description, department, category path, stock status, dimensions
- Reviews (optional) — per-review rating, title, body, author, date, verified-purchase flag, helpful votes, pros/cons, plus an aggregate summary (rating, count, star distribution, recommended count)
- Resume & recurring updates (optional) — turn on Incremental mode to get
only NEW, UPDATED, and REAPPEARED products on every scheduled run, or resume
one specific interrupted crawl with
resumeFromRunId
Modes
🔎 Search
Give one or more keywords (for example oled tv, gaming laptop). Each keyword
resolves to its best-matching department listing, which is then walked page by
page. Narrow results with brand, minimum / maximum price and minimum
rating filters, and order them with sort by.
Pick a Specials / offers category to scrape a promotional collection instead of (or alongside) your keywords:
- Super Deals — the store-wide hottest-deals grid
- Clearance — the run-out / reduced-to-clear range
Discounted products carry the was / original price, the discount amount and
percent, an isOnSpecial flag and the promotion label straight from the
listing — no detail fetch required. Products that are not discounted return
isOnSpecial: false and wasPrice: null; a markdown is never fabricated.
🔗 URL
Paste product URLs (ending in .html) to scrape single products, or paste
department / listing URLs to walk multiple pages of products — including any
specials or department-scoped sale listing URL (for example a TV sale or
laptop sale page). Both are supported in the same run.
Detail enrichment & reviews
Turn on Fetch full product detail + reviews to open each product page and
collect the full specification set, image gallery, description and an aggregate
review summary plus a reviews[] array. Cap the number of reviews per product
with Max reviews per product (0 = all available). With detail off, each
record still carries identity, price and the aggregate rating from the listing.
Products with no reviews simply omit the review fields — they are never faked.
Example input
{"mode": "search","queries": ["oled tv"],"brand": "LG","minPrice": 1000,"maxPrice": 6000,"sortBy": "priceDesc","detailEnrichment": true,"maxReviewsPerProduct": 20,"maxItems": 50,"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "AU" }}
Scrape the store-wide clearance range with was-prices and reviews:
{"mode": "search","specialsCategory": "clearance","detailEnrichment": true,"maxReviewsPerProduct": 10,"maxItems": 50,"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "AU" }}
Example output
Example data below is illustrative.
{"productId": 900123,"sku": "OLED65EXAMPLE","title": "Acme 65-inch 4K OLED Smart TV","name": "Acme 65-inch 4K OLED Smart TV","brand": "Acme","url": "https://www.harveynorman.com.au/acme-65-inch-4k-oled-smart-tv.html","imageUrl": "https://hnau.imgix.net/media/catalog/product/a/c/acme-65-oled.jpg","price": 3495.0,"wasPrice": 3995.0,"discountAmount": 500.0,"discountPercent": 12.5,"isOnSpecial": true,"promotion": "Save $500","currency": "AUD","rating": 4.7,"reviewCount": 128,"brandUrl": "https://www.harveynorman.com.au/brands/acme","description": "Key Features Vivid OLED panel with deep blacks and lifelike colour...","shortDescription": "A 65-inch 4K OLED television with smart features and low-latency gaming.","specifications": {"Product Type": "OLED TVs","Screen Size": "65 inch","Resolution": "4K Ultra HD","Barcode (GTIN)": "9312345678900"},"images": ["https://hnau.imgix.net/media/catalog/product/a/c/acme-65-oled-front.jpg","https://hnau.imgix.net/media/catalog/product/a/c/acme-65-oled-side.jpg"],"stockStatus": "IN_STOCK","gtin": "9312345678900","department": "Audio Visual","category": "OLED TVs","categoryPath": "tv-blu-ray-home-theatre/tvs-by-type/oled-tvs","dimensions": { "height": 82.6, "depth": 4.5, "width": 144.4, "weight": 22.1, "colour": "Black" },"ratingDistribution": { "5": 96, "4": 20, "3": 6, "2": 3, "1": 3 },"recommendedCount": 110,"reviewsCollected": 2,"reviews": [{"reviewId": "100000001","rating": 5,"title": "Stunning picture","body": "Deep blacks and vivid colour, exactly what I hoped for.","author": "SampleReviewer","location": "NSW","date": "2026-06-20T09:15:00.000+00:00","verifiedPurchase": true,"isRecommended": true,"helpfulCount": 4,"notHelpfulCount": 0,"isSyndicated": false,"pros": ["Picture quality"],"cons": null}]}
Tips
- Keep Max products modest while you dial in your keywords and filters, then raise it for a full pull.
- Australian residential proxy is required for reliable results. On the free plan, coverage may be limited and some runs may return no results.
- Use URL mode with a department URL to scrape an entire category.
- Set Max pages per listing to
0(the default) to walk the whole catalogue for a keyword or URL — the run still stops naturally once the storefront's own result total is reached or a page repeats with no new products, so there is no artificial page cap. - Resume a large run: pass a prior run's ID (or dataset ID) as
resumeFromRunIdand the scraper seeds its de-duplication set from that run, appending only products it hasn't seen — handy for topping up a full-catalogue crawl without re-paying for duplicates.
Resume & recurring updates
There are two different things here — pick the one that matches what you're doing:
| Need | Use |
|---|---|
| A crawl stopped and should continue | resumeFromRunId / automatic checkpoint recovery |
| Run the same search every day and receive only changes | incrementalMode |
| Keep separate daily campaigns for similar searches | distinct stateKey values |
| Run a normal full snapshot | leave both off |
Resume (resumeFromRunId) continues one specific interrupted or previous large crawl: paste a run ID or dataset ID and this run skips products already collected there, returning only the remaining new products. An automatic same-run checkpoint also protects against platform migrations/Resurrects without any input needed.
Incremental mode (incrementalMode) is for a schedule (for example, daily): the actor remembers the previous run of the same search by itself, so you never paste a run ID. The first run returns everything as NEW. Later runs return only NEW, UPDATED, and REAPPEARED products by default — duplicates and unchanged products are suppressed (and not charged). Turn on emitUnchanged or emitExpired only when you also want those rows returned (and billed for). State is isolated per mode/search/URL/specials/brand/sort/price/rating/detail setup automatically; set stateKey to name or deliberately share a monitoring campaign. EXPIRED is only synthesized once a run fully scans every keyword/URL/specials target (not capped by Max products/Max pages, not a Resume run).
When incrementalMode is on, every returned record also carries:
| Field | Description |
|---|---|
changeType | NEW | UPDATED | UNCHANGED | REAPPEARED | EXPIRED |
changedFields | Top-level fields that changed since last seen; non-empty only for UPDATED |
firstSeenAt | When this product was first observed by this monitoring campaign |
lastSeenAt | When this product was last observed |
Scheduled-run example — same search, run daily:
Day 1 (first run ever for this search):
{ "mode": "search", "queries": ["oled tv"], "incrementalMode": true }
→ every product comes back with "changeType": "NEW".
Day 2 (the schedule fires again, identical input):
{ "mode": "search", "queries": ["oled tv"], "incrementalMode": true }
→ products whose price/stock/specials/etc. changed come back as "changeType": "UPDATED" with changedFields listing what changed, brand-new products come back as "changeType": "NEW", products that vanished and came back come back as "changeType": "REAPPEARED" — and products that are still there, unchanged, are not returned at all (suppressed, not charged) unless emitUnchanged is on.
Send results into your apps (optional)
Pipe results straight into the tools you already use via Model Context Protocol (MCP) connectors — Notion (a rich page per product), Linear, Airtable or Apify. Authorize a connector under Apify → Settings → API & Integrations, then select it in the input. This never changes the dataset output.