Dan Murphy’s Scraper - Prices, Stock, Ratings & Specials
Pricing
from $1.00 / 1,000 product listings
Dan Murphy’s Scraper - Prices, Stock, Ratings & Specials
Scrape Dan Murphy’s products by category, keyword, or specials. Extract 45+ fields, including regular, sale and member prices, case and unit pricing, stock, ratings, reviews, country, variety, and ABV. Incremental mode tracks changes.
Pricing
from $1.00 / 1,000 product listings
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Dan Murphy's Scraper: Products, Prices & Member Offers
Dan Murphy's Scraper turns danmurphys.com.au, Australia's largest liquor retailer, into structured product data. Get regular, sale and member-offer prices, case and per-unit pricing, ratings, review counts, stock levels and product attributes (country, style, ABV, standard drinks) across 13 departments. Browse by department, search by keyword, filter by brand or specials, or paste category and product links directly, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.
Why This Scraper?
- Two ways to find products. Browse any of 13 verified departments (with sub-department and brand filters), or paste category and product links directly. No need to build URLs by hand.
- Every price that applies, at once. Regular price, sale price, member-only offers, case pricing and per-unit pricing, so you always know which price a shopper actually pays.
- 45+ fields per product. Ratings, review counts, stock levels, country of origin, variety/style, ABV, standard drinks, awards, closures and more.
- Specials and member-offer filters in both modes. Narrow any department, sub-department or pasted category link to only current offers or member deals.
- Built for scheduled price-watch runs. Incremental mode classifies every product NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED between runs, so a recurring schedule reports only what changed.
- Optional detail-page enrichment. Switch on rich descriptions, tasting notes and recommended products only when you need them, charged only for the products it actually fetches.
- A refused run fails loudly instead of returning an empty dataset, so "nothing matched" is never confused with "couldn't be read".
Use Cases
- Price monitoring and comparison tools: track regular, sale and member-offer prices across departments to power price-history or comparison sites.
- Liquor retailers and distributors: watch a competitor's specials, stock levels and new listings in your category.
- Wine and spirits content creators: build rating- and review-based recommendation lists by variety, style, country or ABV.
- Market researchers and analysts: track assortment changes, award-winning products and how often member offers appear over time.
- Personal shopping tools and alerts: get notified when a tracked product or department goes on special.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
stockcode | "812345" |
name | "Sample Brewing Co Pale Ale 6x355mL Cans" |
brand | "Sample Brewing Co" |
department | "beer" |
url | Dan Murphy's link to the product |
price / wasPrice | 45.99 / 52.99 (AUD) |
isOnSpecial / isOnOffer | true / true |
isMemberOffer / memberOfferLabel | true / "Member Price" |
casePrice / singlePrice | 179.99 / 52.99 |
inAnySixPrice | 42.99 |
rating / reviewCount | 4.3 / 87 |
country | "Australia" |
style | "Pale Ale" (beer style, wine variety or spirit type) |
size / packageSize | "355mL" / "6 pack" |
abv / standardDrinks | "4.5%" / "9.8" |
stockQty / purchasable | 240 / true |
deliveryOnly | false |
award / sash | "Gold Medal" / "New" |
imageUrl | product image link |
richDescription / tastingNotes | long-form description / tasting notes (when fetchDetails is on) |
recommendedStockcodes | related product stock codes (when fetchDetails is on) |
changeType / changedFields | "UPDATED" / ["price"] (incremental mode) |
firstSeenAt / lastSeenAt | ISO timestamps |
Also carried when present: description, promotionType, packMessage, casePackMessage, unit, closure, foodMatch, isNew, imageLarge, and detailFetched (true only on a product whose detail payload was actually fetched this run).
How to Use
- Pick a mode:
search(department, sub-department, keyword, brand) orurl(paste category or product links). - Fill in the fields for that mode, and switch on
specialsOnly/memberOffersOnlyif you only want current or member offers. - Set Max products per run to control run size and cost (it applies to each scope separately, see the tip below), then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Browse a department with a specials filter:
{"mode": "search","department": "beer","subDepartment": "craft beer","specialsOnly": true,"maxProducts": 50}
Keyword search plus a department (two scopes in one run):
{"mode": "search","department": "red-wine","searchTerm": "shiraz","maxProducts": 100}
The keyword runs as its own site-wide search next to the department scope; it is not narrowed to the department, and the specials, member-offer and brand filters do not apply to it.
Paste a category link, member offers only:
{"mode": "url","urls": ["https://www.danmurphys.com.au/whisky/scotch-whisky"],"memberOffersOnly": true,"maxProducts": 0}
Recurring price-watch run (scheduled, incremental):
{"mode": "search","department": "spirits","incrementalMode": true,"emitExpired": true,"maxProducts": 0}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/danmurphys-scraper").call(run_input={"mode": "search", "department": "beer", "maxProducts": 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/danmurphys-scraper').call({ mode: 'search', department: 'beer', maxProducts: 50 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Caps and run size
Max products per run is counted per scope, not across the whole run. Each scope (the keyword search, the department, and every pasted category link) scans up to that many products on its own, so a run with a keyword and a department can return up to twice the cap, and three pasted category links up to three times it. Pasted product links are not counted against the cap at all. To bound a run's total size, divide your budget by the number of scopes. Max pages per scope (24 products per page) also applies to each scope separately.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted run: paste its run id and products it already collected are skipped, so you don't pay twice. It cannot be combined with incremental mode: the two solve different problems (one continues a single run, the other tracks a recurring scope), and the run refuses to start if both are set. - Incremental mode (
incrementalMode) is for scheduled runs over the same search. Each product is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEAREDorEXPIRED(only after a run that scanned its whole tracked scope).stateKeynames or shares the stored baseline; leave it empty to auto-key on mode, department and filters.
Tip: use maxProducts: 0 (or a cap larger than the scope) for incremental monitoring. The cap counts products scanned, including unchanged ones, and every run starts again from the first page. A capped incremental run therefore re-checks the same first products every time: price changes, new listings and removals further down the list are never seen, and the EXPIRED pass is skipped because the scan never finishes. Once those first products stop changing, a capped run can return 0 rows and log "No products matched" even though it scanned its full allowance; that means "nothing changed in the part that was scanned", not "nothing changed". The default cap is 20, so raise it before scheduling.
Tip: emitExpired batches are not limited by maxProducts. maxProducts caps how many live listings each scope scans; the EXPIRED pass is a separate comparison against the whole remembered baseline for that scope, and every product missing from this run's complete scan is pushed as EXPIRED in the same run, however many that turns out to be. If a tracked scope shrinks a lot between scheduled runs (for example a specials filter that has far fewer current specials today than last time), a run with emitExpired on can push and bill noticeably more EXPIRED rows than maxProducts allows. Start a fresh stateKey (or narrow the scope) if you are monitoring something that can shrink sharply, and check the run log's change-count summary before widening a schedule.
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 product, 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, or a compatible MCP target).
- Select it in the MCP connectors input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where products 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 (department / keyword) or url (paste category or product links). |
department | string | beer | Verified department slug. Wine splits into red-wine, white-wine, champagne-sparkling, fortified-wine. |
subDepartment | string | (none) | Second path segment, with spaces (e.g. craft beer, shiraz, scotch whisky). Leave empty for the whole department. |
searchTerm | string | (none) | Free-text search. If given, a keyword scope runs in addition to the department scope (site-wide; department, brand and offer filters do not apply to it). |
brand | string | (none) | Brand facet slug (lowercase, dashes for spaces). Search mode only. |
urls | array | sample category link | Category routes and/or product links. Multi-URL supported; pagination walks forward automatically. |
specialsOnly | boolean | false | Only products with a current offer. Applies to the department scope and every URL-mode category (not to the keyword scope or pasted product links). |
memberOffersOnly | boolean | false | Only products carrying a member (My Dan Murphy's) offer. Applies to the department scope and every URL-mode category (not to the keyword scope or pasted product links). |
fetchDetails | boolean | false | Fetch each pushed product's detail payload (rich description, tasting notes, recommendations). Adds a per-product surcharge. |
maxPages | integer | 0 | Cap on pages walked per scope. 0 walks until the department is exhausted. |
maxProducts | integer | 20 | Cap on products scanned, applied to each scope separately (pasted product links are not counted). 0 = unlimited. Use 0 for incremental monitoring. |
resumeFromRunId | string | (none) | Continue one interrupted run. Cannot be combined with incremental mode. |
incrementalMode | boolean | false | For scheduled monitoring: classify every product NEW / UPDATED / UNCHANGED / REAPPEARED / EXPIRED against the previous run of the same search. |
stateKey | string | (none) | Manual key for the incremental baseline. Leave empty to auto-key on mode, department and filters. |
emitUnchanged | boolean | false | Incremental mode only. Also return (and bill) products classified UNCHANGED. |
emitExpired | boolean | false | Incremental mode only. Also return (and bill) products that vanished since the last complete run. |
proxyConfiguration | object | Apify Proxy (datacenter) | Connection settings. Switch to Apify Residential with country AU if you see blocks. |
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 products are created. |
maxNotifyListings | integer | 0 | Cap on items exported to connectors per run. 0 exports everything pushed. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"stockcode": "812345","name": "Sample Brewing Co Pale Ale 6x355mL Cans","url": "https://www.danmurphys.com.au/product/812345/sample-brewing-co-pale-ale-6x355ml-cans","description": "Sample Brewing Co Pale Ale 6x355mL Cans","brand": "Sample Brewing Co","department": "beer","price": 45.99,"wasPrice": 52.99,"isOnSpecial": true,"isOnOffer": true,"isMemberOffer": true,"memberOfferLabel": "Member Price","promotionType": "member offer","casePrice": 179.99,"singlePrice": 52.99,"inAnySixPrice": 42.99,"unit": "Each","packageSize": "6 pack","abv": "4.5%","standardDrinks": "9.8","country": "Australia","style": "Pale Ale","size": "355mL","rating": 4.3,"reviewCount": 87,"stockQty": 240,"purchasable": true,"imageUrl": "https://cdn.danmurphys.com.au/images/812345-medium.jpg","scrapedAt": "2026-09-30T04:00:00Z","changeType": "UPDATED","changedFields": ["price", "stockQty"],"firstSeenAt": "2026-08-01T04:00:00Z","lastSeenAt": "2026-09-30T04:00:00Z"}
Plan Requirement
The default proxy setting works out of the box on any plan. If you ever see blocks, switch to the Apify Residential proxy group with country AU under Connection.
FAQ
How much does it cost?
You pay per product returned, plus an optional per-product surcharge only for products whose detail page you chose to fetch (fetchDetails). The Pricing tab shows the current rates. Use Max products per run to cap cost; it applies to each scope separately, so a run with a keyword plus a department, or several pasted category links, can return a multiple of it.
Is it legal to scrape Dan Murphy's?
This actor collects only publicly available product data. You are responsible for how you use it: follow Dan Murphy's terms and the laws that apply to you, including any age-verification and liquor-advertising rules in your jurisdiction, and get legal advice if you plan commercial redistribution. Dan Murphy's requires visitors to be of legal purchasing age; make sure your use of this data respects that.
Can I get only new or changed prices on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated, reappeared or expired products, and unchanged ones are not billed unless you turn on Emit unchanged products. Set Max products per run to 0 for this: a capped run re-checks only the same first products every time and never detects expired ones.
Why does the "wine" department not work?
wine on its own is not a valid department slug. It splits into red-wine, white-wine, champagne-sparkling and fortified-wine. Use one of those, and optionally narrow it further with Sub-department (optional) (for example shiraz).
Why did my run fail instead of returning an empty dataset?
If the site refuses every request, the run stops with a clear message so "no products matched" is never confused with "nothing could be read". Run it again in a few minutes, or switch the proxy group in the input.
Can emitting expired products push more rows than my Max products setting?
Yes, and this is worth knowing before you schedule a wide monitoring run. Max products per run caps how many live listings a run scans, but it does not cap the EXPIRED batch: that batch compares the whole remembered baseline for a tracked scope against this run's complete scan, so if the scope has shrunk a lot since the last complete run, turning on Emit expired products can push (and bill) more EXPIRED rows in one run than Max products per run allows. Start a fresh State key for scopes that can shrink sharply, or check the run log's change-count summary before widening a schedule.
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 or another compatible connector.
🔗 Want more wine and drinks data?
Pair this actor with these related scrapers from the same team:
| 🍷 Untappd Beer, Brewery and Check-in Scraper Scrape Untappd beers, breweries, venues and check-ins by keyword, brewery, Top Rated... | 🥦 Woolworths AU Scraper Scrape Woolworths Australia (woolworths.com.au) grocery products and reviews. Search by... |
| 🍷 Vivino Wine Scraper From $1.2/1K. Scrape Vivino.com for wine ratings, prices, taste profiles, food pairings... | 🍷 Wine-Searcher Scraper Look up wines on wine-searcher.com by name, URL, or LWIN code. Returns 30+ fields... |
| 🥦 ALDI AU Scraper Scrape ALDI Australia (aldi.com.au) products: name, brand, price, was-price, savings... | 🍷 Wolt.com From $0.8/1K. Scrape Wolt restaurants and full menus at the city scale. Extract 60+... |
💬 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.