Dirk van den Broek Product Scraper
Under maintenancePricing
from $4.00 / 1,000 product results
Dirk van den Broek Product Scraper
Under maintenanceScrape every Dirk van den Broek (dirk.nl) product from the official web GraphQL API: name, brand, store-specific price, offer/discount, unit price, pack size, category and image. Clean JSON/CSV, no login needed. Filter by category (webGroupId) and pick a store. Failed lookups are never billed.
Pricing
from $4.00 / 1,000 product results
Rating
0.0
(0)
Developer
Elena Vance
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Dirk van den Broek Product Scraper — Prices, Discounts, Unit Prices & Images from Dirk.nl
Turn the entire Dirk van den Broek (dirk.nl) assortment into clean, structured JSON or CSV: product name, brand, current price, offer/discount, per-unit price (€/kg, €/l), pack size, category, image, and the product link — one tidy record per product.
Browse the whole catalog by category, or scrape the full assortment, and get back data ready to drop into a spreadsheet, database, price-comparison site, or app. No login, no account, no HTML wrangling — and you are never billed for failed requests.
Good to know — prices are per store. Dirk's prices are store-specific, so every run targets one store via a Store ID (default 9 = Katwijk). Change the Store ID in the input to get the prices a different Dirk location shows. One run = one store's price list.
Why this Actor
- Real store-level pricing. Dirk publishes prices per location, and this Actor targets exactly the store you choose. Pick the store nearest your use case and get the prices its shoppers actually see — not a generic list.
- Offers and discounts, detected for you. Each record carries the current
price, the pre-discountpriceBeforeOffer, thenormalPrice, anisOfferflag, adiscountLabel(e.g.25% korting), and the offer'sstartDate/endDate— filter the whole assortment down to this week's deals in one expression. - Per-unit prices for real comparison.
pricePerUnit+pricePerUnitType(per kg, l, or piece) are parsed from Dirk's pack-size text, so you can compare value across pack sizes — and against other supermarkets. - The full assortment, or a focused slice. Leave the category filter empty to scrape every category for your store, or pass specific category IDs.
- Complete product detail. Brand, pack size, department + category, the product image, max purchase amount, weight-product flag, and the canonical dirk.nl product URL — one normalized record.
- You never pay for failures. Timeouts, removed products, and price-less rows are reported in the run summary — not written to your dataset and not billed.
- Fast and browserless. No headless browser, so runs are quick and compute stays minimal.
- Clean, consistent EUR output. Prices as euro floats, whitespace-normalized text, JSON-safe values throughout.
Problems this Actor solves
| If you are… | Your problem | How this Actor solves it |
|---|---|---|
| A price-comparison / deals site | Keeping a grocery price database current by hand is impossible | Schedule a daily run; ingest every product with price, offer, and unit price as JSON |
| A market researcher / analyst | Grocery-price and inflation tracking needs structured, repeatable data | Dated, normalized records per product — export straight to pandas, Sheets, or BI |
| A category manager at another retailer | Benchmarking a competitor's assortment and pricing is slow and partial | Full category-level coverage with price and unit price for a chosen store in one run |
| An app / chatbot / agent developer | You need Dirk catalog data without building and babysitting a scraper | Pay per record on demand; a stable, normalized schema you can rely on |
| A deal hunter / content creator | Finding the best weekly discounts means clicking through the site | Pull the assortment and filter on isOffer / discountLabel |
What data you get
Each available product becomes one dataset record:
| Field | Description |
|---|---|
id / productId | Dirk's stable product ID (the record's unique id; deduped on this) |
title | Product name (Dirk's header + sub-text, combined) |
brand | Brand name, when present (null otherwise) |
description | Reserved; currently null (no long description is available) |
categoryId / categoryName | The category ID and its name |
department / webgroup | Dirk's department and category labels |
price | Current price as a EUR float (offer price when on offer, else normal price) |
currency | Always EUR |
normalPrice | The regular (non-offer) price as a EUR float |
priceBeforeOffer | The pre-discount price when on offer (else null) |
isOffer | true when the product is discounted |
discountLabel | e.g. 25% korting — computed from old/new price |
startDate / endDate | The offer's validity window, when on offer |
unitSize | Pack / sales unit text (e.g. 500 g, 1 l, 6 stuks) |
pricePerUnit / pricePerUnitType | Per-unit price and its unit (kg, l, piece) |
isWeightProduct | true for weight-priced items (e.g. loose produce) |
maxAmount | Max purchasable quantity, when set |
storeId | The store the prices came from (e.g. 9 = Katwijk) |
imageUrl | Product image (absolute URL) |
productUrl | Canonical dirk.nl product page |
source | Constant tag identifying the producing Actor |
scrapedAt | ISO 8601 timestamp of the run |
rawData | Optional: the full raw Dirk product object, when Include raw data is on |
Example output
{"id": "12345","productId": 12345,"title": "Verse halfvolle melk 1 l","brand": "Dirk","description": null,"categoryId": "1","categoryName": "Zuivel","department": "Zuivel, eieren","webgroup": "Zuivel","price": 0.95,"currency": "EUR","normalPrice": 1.19,"priceBeforeOffer": 1.19, // present because this product is on offer"isOffer": true,"discountLabel": "20% korting","startDate": "2026-06-16","endDate": "2026-06-22","unitSize": "1 l","pricePerUnit": 0.95, // i.e. € 0.95 / l"pricePerUnitType": "l","isWeightProduct": false,"maxAmount": 99,"storeId": 9,"imageUrl": "https://web-fileserver.dirk.nl/product-images/12345.jpg","productUrl": "https://www.dirk.nl/boodschappen/zuivel-eieren/zuivel/verse-halfvolle-melk-1-l/12345","source": "dirk-product-scraper","scrapedAt": "2026-06-18T08:30:00+00:00"}
Rows that could not be fetched (or that came back without a usable price — usually
a wrong Store ID) are not written to the dataset (and never billed). Request
failures are listed in the run's SUMMARY record in the key-value store —
{ "failures": [ { "input": "…", "error": "…" } ] } —
and the run's status message tells you at a glance how many products succeeded.
How to use it (60 seconds)
- Click Try for free / Start.
- Choose your Store ID (default
9= Katwijk) — prices are per store, so this picks whose price list you get. - Choose what to scrape:
- Everything (default): leave Category IDs empty to scrape the full Dirk assortment for that store.
- Specific categories: add one category ID per line (e.g.
1).
- Click Save & Start. Download results as JSON, CSV, Excel, or via the Apify API from the Dataset tab; check Key-value store → SUMMARY for run totals and any failed requests.
Input reference
| Field | Type | Default | Description |
|---|---|---|---|
| Category IDs | list | (empty) | One Dirk category ID per line to scrape only those categories. Empty = scrape all categories (full assortment). |
| Store ID | integer | 9 (Katwijk) | The Dirk store whose prices are returned — prices are store-specific. A default store is preselected; change it to get another location's prices. |
| Include raw data | boolean | false | Adds the full raw Dirk product object under rawData. Increases item size. |
| Proxy configuration | object | Apify Automatic | Automatic (datacenter) proxies keep cost near zero. Switch to Dutch (NL) residential only if you ever see blocked requests. |
| Max concurrency | integer | 5 | Parallel requests (1–20). Kept moderate to be respectful. |
| Delay between requests | integer | 0 | Politeness delay in seconds before each request (0–10). 0 is fine. |
| Max items | integer | 0 | Stop after N product records (0 = unlimited). |
Good to know
Products are de-duplicated by product ID across categories, prices come through as euro values, and image links are returned as absolute URLs.
A product whose price can't be read for the chosen store is skipped — so if a run comes back nearly empty, check the Store ID first.
Pricing — what a run costs
This Actor uses transparent pay-per-event pricing with a built-in volume discount: a small Actor-start fee, a fixed price per successful product record for the first 10,000 results of a run, and a cheaper rate for every result beyond that. No subscription, no minimums, and failures are never charged. The exact per-result rate is shown on the Actor's Pricing tab.
- Failed requests are free. Timeouts, removed products, and price-less rows are reported in the summary, never billed.
- Bigger runs cost less per item. The discount tier resets per run, so one large run is cheaper than the same job split into many small ones.
- Try it free: an Apify free account includes $5 of monthly platform credit — enough to try the Actor before paying anything.
- Stay in control: set Max items and Apify's maximum charge per run; the Actor stops gracefully at your cap, keeping everything already scraped.
Compared to the alternatives
| This Actor | Build your own scraper | Manual checking | |
|---|---|---|---|
| Full assortment, normalized | Yes | You maintain it | Impractical |
| Per-store pricing | Yes | You build and maintain it | One store at a time |
| Offers & discount labels | Yes | You maintain it | One product at a time |
| Per-unit prices (€/kg, €/l) | Yes | You compute it | Mental math |
| No login / no account needed | Yes | You build and maintain it | – |
| Never billed for failures | Yes | – | – |
| Export JSON / CSV / Excel / Apify API | Yes, built-in | DIY | Copy-paste |
| Setup time | ~60 seconds | Days; breaks on schema changes | Hours per run |
Integrate the data
- Exports: JSON, CSV, Excel, XML from the Dataset tab — or fetch
programmatically:
GET https://api.apify.com/v2/datasets/{datasetId}/items?format=json
- Run on a schedule: use Apify Schedules to refresh prices daily or weekly, and webhooks to push finished runs into your pipeline (Sheets, Slack, your backend).
- From code: call the Actor with the Apify API or SDKs (Python / JavaScript) and read the dataset when the run finishes.
- Run summary: every run writes a
SUMMARYrecord (key-value store) with totals, successes, failures, the store ID used, and billing counts — ideal for monitoring automated pipelines.
FAQ
Do I need a Dirk account or login? No. There is no login and no account needed — just set your inputs and run.
Are prices the same everywhere?
No — Dirk's prices are store-specific. You pick a Store ID (default 9 =
Katwijk) and get that store's prices. Run again with a different Store ID to
compare locations.
How do I pick a different store? A default store is preselected. Set the Store ID input to another Dirk store to get that location's prices.
Why did my run come back nearly empty?
Almost always an invalid Store ID: when prices can't be resolved for that
store, products have no usable price and are skipped. Try the default (9) or
another valid store.
How do I get only discounted products?
Scrape, then filter on isOffer == true (or a non-null discountLabel); the offer
window is in startDate / endDate.
Do I need a proxy? No. The default Automatic (datacenter) proxy works and keeps cost low. Switch to Dutch (NL) residential only if you ever see blocked requests.
How fresh is the data? Each run fetches live data, so you get exactly what dirk.nl shows for that store at that moment. Schedule the Actor to keep your dataset as fresh as you need.
What formats can I export? JSON, CSV, Excel, XML — from the Console or via the Apify API.
Related Actors
Part of a family of Dutch-supermarket product scrapers that all share the same clean schema and pay-per-event billing — mix and match for full market coverage:
- Albert Heijn Product Scraper — the largest NL chain; national Bonus pricing.
- Lidl Product Scraper — includes Lidl Plus member prices. Pairs with the Lidl Category Scraper (map the category tree first, then scrape products).
- Plus Product Scraper — per-store pricing, like Dirk.
- DekaMarkt Product Scraper — also store-specific pricing (storeId), the closest sibling to this Actor.
- Hoogvliet Product Scraper — pairs with the Hoogvliet Category Scraper (run category first to map the tree, then product).
Same EUR-normalized output, offer/unit-price fields, and "never billed for failures" guarantee across every chain — so one pipeline can ingest the whole Dutch grocery market with a consistent record shape.
Disclaimer
This Actor is intended for personal and research use. You are responsible for ensuring your use complies with Dirk van den Broek's terms and applicable law. Please scrape responsibly — keep concurrency moderate and delays reasonable. This project is not affiliated with, endorsed by, or sponsored by Dirk van den Broek.