HORNBACH Products, Prices & Reviews Scraper avatar

HORNBACH Products, Prices & Reviews Scraper

Pricing

from $1.00 / 1,000 product results

Go to Apify Store
HORNBACH Products, Prices & Reviews Scraper

HORNBACH Products, Prices & Reviews Scraper

Scrape HORNBACH (hornbach.de) DIY, building & garden products: current + strike-through price with discount, per-unit pricing (m2/kg/piece), full technical specs, category path, online & in-store availability, and complete product reviews with rating breakdown.

Pricing

from $1.00 / 1,000 product results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

1

Bookmarked

16

Total users

4

Monthly active users

7 days ago

Last modified

Share

Hornbach.de Scraper: Prices, Stock, Specs and Reviews

Hornbach.de Scraper turns Hornbach.de, the German DIY, building materials, and garden retailer, into a clean product data feed. Get the current price alongside the manufacturer's suggested price and computed discount when a product is marked down, per-square-metre/per-kilogram/per-piece pack pricing where the site shows it, full technical specifications, breadcrumb category paths, online and in-store availability, and complete customer review histories with a star-rating breakdown. Search by keyword and/or category with the site's own filters, or paste product, search, and category links directly, then export to JSON, CSV, or Excel, or pull results straight into your app through the API.

Why This Scraper?

  • Was-price and discount, structured. When Hornbach.de shows both its own price and a manufacturer's suggested price, both are captured, plus the computed discount amount and percentage, not just a badge.
  • Unit pricing for bulk goods. Tiles, flooring, and similar products sold by quantity return their per-square-metre, per-kilogram, or per-piece pack price alongside the item price, exactly as shown on the product page.
  • Full technical specifications on demand. Turn on full product detail for the complete breadcrumb category path, EAN, media gallery, variant matrix, and every characteristic the product page lists, returned as clean key and value pairs.
  • Complete review history, fetched by default. Overall rating, review count, a full one to five star rating breakdown, and every individual review with author, date, rating, title, and body text.
  • Online and in-store availability together. Home delivery status alongside store pickup or reservation status and seller information, plus exact aisle-level stock text when full detail is on.
  • Three ways in. Keyword and/or category search with the site's real filters, or paste product, search, or category links and let pagination continue automatically.
  • Built for schedules. Incremental mode tracks one search over time and returns only what changed on later runs, or resume one interrupted run by pasting its run or dataset id.

Use Cases

  • Price and discount monitoring: track the gap between the manufacturer's suggested price and Hornbach.de's own price, plus per-unit pricing, for repricing or comparison-shopping tools.
  • Building materials procurement: pull bulk per-square-metre or per-kilogram pricing and full technical specifications for tiles, timber, and other quantity-sold materials.
  • Catalog and inventory feeds: keep an external catalog current with online and in-store availability, seller information, and specifications.
  • Review and reputation research: collect full review histories with rating breakdowns to analyze product quality and customer sentiment.
  • Recurring change monitoring: schedule daily or weekly runs to catch new arrivals, price changes, and availability shifts without re-collecting everything each time.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
productId / sku"12314733"
name"Sample Cordless Drill Driver, incl. 2 batteries and charger"
brand"Sample Tools Professional"
url"https://www.hornbach.de/p/sample-product-name/12314733/"
price / currency / priceUnit199.0 / "€" / "ST"
originalPrice249.0 (manufacturer's suggested price, present when the product is marked down)
discountAmount / discountPercent50.0 / 20.1
packPrice / packPriceUnit14.93 / "m²" (per-square-metre, per-kilogram, or per-piece pack price, when the site shows one)
rating / reviewCount4.9 / 11
badges["Top item"]
onlineAvailable / onlineAvailabilityTexttrue / "Online bestellbar"
storePickupAvailable / storePickupAvailabilityTexttrue / "Reservierbar"
onlineMerchant / storeMerchant{"name": "HORNBACH", "isMarketplaceMerchant": false}
categoryPath[{"name": "Home", "url": "..."}, {"name": "Machines, Tools and Workshop", "url": "..."}] (full breadcrumb, with full product detail on, or for a pasted product URL)
ean"4000000000000" (with full product detail on, or for a pasted product URL)
specifications{"Drive type": "Battery", "Voltage": "18 V", "Weight incl. battery": "2.1 kg"} (with full product detail on, or for a pasted product URL)
images[{"url": "...", "thumbnailUrl": "...", "alt": "..."}] (full media gallery, with full product detail on, or for a pasted product URL; otherwise a single image / thumbnailUrl pair is returned instead)
datasheets[{"title": "Technical data sheet", "url": "..."}] (with full product detail on, or for a pasted product URL)
storeStockText / storeAisleText"20 pcs in stock at the store" / "Aisle 12" (with full product detail on, or for a pasted product URL)
reviews.averageRating / reviews.totalReviewCount4.9 / 11
reviews.ratingDistribution[{"rating": 5, "count": 10}, {"rating": 4, "count": 1}] (only when reviews are fetched)
reviews.items[][{"rating": 5, "title": "...", "body": "...", "author": "...", "date": "..."}] (only when reviews are fetched)
changeType"NEW" (Incremental mode only; also UPDATED, UNCHANGED, REAPPEARED, EXPIRED)
changedFields["price", "onlineAvailabilityText"] (Incremental mode, UPDATED rows only)
firstSeenAt / lastSeenAt"2026-08-01T00:00:00Z" / "2026-08-04T00:00:00Z" (Incremental mode only)

How to Use

  1. Pick a mode: search (keyword and/or category with Hornbach.de's own filters) or url (paste product, search, or category links).
  2. For search mode, set a keyword (optionally narrowed by a category id) and filter by brand, seller, price, or availability; a category id alone browses the whole department without filters. For url mode, paste the links instead.
  3. Turn on Fetch full product detail and/or adjust Fetch reviews for the depth you need, then set Max products total to control run size and cost.
  4. Click Start, then download the dataset as JSON, CSV, or Excel, or read it through the API.

Basic keyword search:

{
"mode": "search",
"searchTerm": "akkuschrauber",
"maxItems": 20
}

Search narrowed by category, brand, and price:

{
"mode": "search",
"searchTerm": "akkuschrauber",
"category": "S1937",
"brands": ["Bosch Professional"],
"minPrice": 50,
"maxPrice": 250,
"sortBy": "PRICE_ASC",
"maxItems": 30
}

Category browse with full detail and review enrichment:

{
"mode": "search",
"category": "S594",
"fetchDetails": true,
"fetchReviews": true,
"maxReviewsPerProduct": 0,
"maxItems": 50
}

Paste product, search, or category links:

{
"mode": "url",
"urls": [
"https://www.hornbach.de/p/sample-product-name/12314733/",
"https://www.hornbach.de/s/fliesen/",
"https://www.hornbach.de/c/baustoffe/S594/"
],
"maxItems": 40
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/hornbach-de-scraper").call(run_input={"mode": "search", "searchTerm": "akkuschrauber", "maxItems": 20})
for product in client.dataset(run["defaultDatasetId"]).iterate_items():
print(product["name"], product["price"], product["currency"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/hornbach-de-scraper').call({ mode: 'search', searchTerm: 'akkuschrauber', maxItems: 20 });
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 specific interrupted or previous run: paste its run id or dataset id and this run skips products already collected there, returning only the remainder. It also protects automatically against a platform migration or restart mid-run, with no input needed.
  • Incremental mode (incrementalMode) is for scheduling the same search again and again, for example daily: the actor remembers the previous run of that same tracked search itself, so no run id needs to be pasted. The first run returns every matching product as NEW. A later run compares against that baseline and returns only NEW, UPDATED and REAPPEARED products, with changedFields listing what changed; products that have not changed are suppressed and not billed, unless emitUnchanged is turned on. Turning on emitExpired also returns baseline products that a complete scan of the tracked search no longer found, marked EXPIRED; this only fires when the run was not resumed, was not capped by Max products total, and reached the natural end of every search, category, or URL in scope. A product only comes back marked REAPPEARED after an earlier complete scan with Emit expired on recorded it as gone (normally output as an EXPIRED row) and it then turns up again; a tracked product that was never marked gone that way instead classifies as UPDATED, or UNCHANGED (suppressed unless Emit unchanged is on), like any other tracked product, never REAPPEARED. State is isolated automatically per search/category/URL, filter, and detail/review settings; set stateKey to name or deliberately share a monitoring campaign.
  • Pasting resumeFromRunId together with incrementalMode only bootstraps a brand-new tracked search from an existing dataset. If that state key already has a saved baseline, the run stops with an error instead of mixing the two, so nothing is collected or charged.

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 record, 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.

  1. Authorize a connector once under Apify > Settings > Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. If the picker is empty, you have not authorized a connector yet.
  3. For Notion, also set notionParentPageUrl to the page where items 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

ParameterTypeDefaultDescription
modestringsearchsearch (keyword/category with filters) or url (paste links).
searchTermstringnone (prefill: akkuschrauber)Free-text keyword for search mode. URL mode reads the term from the pasted URL instead.
categorystringnoneA Hornbach.de category id, e.g. S1937. Narrows a keyword search, browses a whole department alone, and also applies to a pasted search-result URL in URL mode; a category or product URL ignores it.
brandsarraynone (prefill: [])Only these brands. Applies to a keyword search (with or without a category) and to a pasted search-result URL in URL mode. Ignored for a category-only browse (no keyword) and for pasted category or product URLs.
sellersarraynone (prefill: [])Only these named sellers. Same scope as brands.
minPriceintegernoneMinimum price in EUR. Same scope as brands.
maxPriceintegernoneMaximum price in EUR. Same scope as brands.
availabilitystring`` (any)IN_STOCK, ONLINE, RESERVABLE, or NEW. Same scope as brands.
sortBystringSCORESCORE, PRICE_ASC, PRICE_DESC, RATING_DESC, BRAND_ASC, BRAND_DESC, TITLE_ASC, TITLE_DESC. Same scope as brands.
urlsarraynone (prefill: ["https://www.hornbach.de/s/akkuschrauber/"])Product, search, or category links for URL mode.
fetchDetailsbooleanfalseAdds the full breadcrumb path, description, flattened specifications, EAN, media gallery, variant matrix, and exact in-store stock text. Keyword and search-URL results already include current price, was-price/discount, pack price, and rating without this toggle; category-browse results (category id without a keyword, or a pasted category URL) include only price, rating, and basic availability unless this toggle is on. A pasted product URL is always scraped from its full product page, so it always returns these detail fields and always counts as enriched, even with this toggle off.
fetchReviewsbooleantrueFetches each product's full review history. Off leaves a rating/count summary with no individual reviews.
maxReviewsPerProductinteger20Cap on reviews fetched per product when Fetch reviews is on; 0 = all available.
maxPagesinteger0Cap on result pages per search/category/URL entry; 0 = unlimited, walk every page until the site's own last page or Max products total is hit.
maxItemsinteger20Hard cap on total products returned across every entry; 0 = unlimited.
resumeFromRunIdstringnoneContinue one specific previous run or dataset: already-collected products are skipped. For recurring monitoring of the same search, use Incremental mode instead.
incrementalModebooleanfalseTrack this same search/category/URL set across scheduled runs and return only what changed. See "Resume and recurring updates" above.
stateKeystringnoneName a monitoring campaign, or deliberately share state across differently-configured runs. Left empty, a key is derived automatically from the search, filters, and detail/review settings.
emitUnchangedbooleanfalseIncremental mode only. Also return (and bill) products unchanged since the last run, marked UNCHANGED.
emitExpiredbooleanfalseIncremental mode only. Also return (and bill) products from the baseline no longer found, marked EXPIRED, once a run completes a full scan of the tracked search.
proxyobject{"useApifyProxy": true}Connection configuration.
mcpConnectorsarraynoneOptional MCP connectors to also receive a summary of results.
notionParentPageUrlstringnoneRequired only when a Notion connector is selected.
maxNotifyListingsinteger50Cap on items sent to each connector; does not affect the dataset.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"productId": "12314733",
"sku": "12314733",
"concreteProductId": "12314733_ST",
"name": "Sample Cordless Drill Driver, incl. 2 batteries and charger",
"url": "https://www.hornbach.de/p/sample-product-name/12314733/",
"brand": "Sample Tools Professional",
"price": 199.0,
"currency": "€",
"priceUnit": "ST",
"originalPrice": null,
"discountAmount": null,
"discountPercent": null,
"packPrice": null,
"packPriceUnit": null,
"badges": ["Top item"],
"rating": 4.9,
"reviewCount": 11,
"onlineAvailable": true,
"onlineAvailabilityText": "Online bestellbar",
"storePickupAvailable": true,
"storePickupAvailabilityText": "Reservierbar",
"onlineMerchant": { "name": "HORNBACH", "isMarketplaceMerchant": false },
"storeMerchant": { "name": "HORNBACH", "isMarketplaceMerchant": false },
"categoryPath": [
{ "name": "Home", "url": "https://www.hornbach.de/" },
{ "name": "Machines, Tools and Workshop", "url": "https://www.hornbach.de/c/sample/S1937/" }
],
"ean": "4000000000000",
"specifications": {
"Drive type": "Battery",
"Voltage": "18 V",
"Weight incl. battery": "2.1 kg"
},
"images": [
{ "url": "https://media.hornbach.de/hb/packshot/sample.jpg", "thumbnailUrl": "https://media.hornbach.de/hb/packshot/sample_thumb.jpg", "alt": "Sample product image" }
],
"datasheets": [
{ "title": "Technical data sheet", "url": "https://media.hornbach.de/sample.pdf" }
],
"reviews": {
"averageRating": 4.9,
"totalReviewCount": 11,
"ratingDistribution": [
{ "rating": 5, "count": 10 },
{ "rating": 4, "count": 1 }
],
"items": [
{
"rating": 5,
"title": "Sample review title",
"body": "Sample review text describing the product experience.",
"author": "Sample User",
"date": "2026-05-01T00:00:00.000Z",
"isRecommended": true,
"secondaryRatings": { "Value": 5, "Quality": 5 }
}
]
}
}

Plan Requirement

Hornbach.de Scraper is priced per product returned, plus a small per-product surcharge only when full product detail and/or reviews are fetched for that product. The default connection setting works out of the box, so no extra setup is required for typical runs. For very large or sustained monitoring, selecting a residential connection under Connection can give more headroom.

FAQ

How much does it cost?

You pay per product returned, plus a per-product surcharge only when full product detail and/or reviews are actually fetched for that product. The Pricing tab shows the current rates. Use Max products total to cap the cost of any run.

This actor collects only publicly available product data. You are responsible for how you use it: follow Hornbach.de's 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 images 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 later run then returns only new, updated and reappeared products for that tracked search, and unchanged ones are suppressed and not billed unless you turn Emit unchanged on.

What is the difference between Resume and Incremental mode?

Resume (resumeFromRunId) continues ONE specific interrupted or previous run: paste its run or dataset id and only the remaining new products are returned. Incremental mode is for running the SAME search again and again on a schedule; the actor remembers the previous run of that search by itself, with no id to paste. Combining the two only bootstraps a brand-new tracked search from an existing dataset; if that search already has saved state, the run stops with an error instead of mixing the two.

When does a product come back marked REAPPEARED?

Only after an earlier complete scan with Emit expired on recorded that same product as gone (normally output as an EXPIRED row), which itself only happens when Emit expired was on and that earlier run completed a full, uncapped scan of the tracked search. A tracked product that was never marked gone that way instead classifies as UPDATED, or UNCHANGED (suppressed unless Emit unchanged is on), like any other tracked product, never REAPPEARED.

Why might a run fail, or come back empty, instead of returning products?

A run only fails outright for an invalid Resume id, or for combining Resume with Incremental mode on a search that already has saved state; both stop before anything is collected or charged. If Hornbach.de cannot be reached at all during a run, or a search request is set up with no keyword and no category, the run finishes normally with zero products and a message in the log, rather than failing, so "nothing found" and "the site could not be reached" both stay visible without a false failure status.

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:

🛒 OBI.de Scraper
Scrape OBI (obi.de) DIY/home-improvement products: current + strike-through original...
🛒 ROSSMANN.de Scraper
Scrape ROSSMANN (rossmann.de) drugstore products: current + original strike-through price...
🛒 dm.de
Scrape dm-drogerie markt (dm.de) products: current + strike-through Ausverkauf price with...
🥦 Kaufland.de Scraper
Scrape Kaufland.de, Germany's hypermarket and online marketplace: keyword/category/brand...
🛒 Thalia.de Scraper
Scrape Thalia.de books, eBooks, audiobooks, toys and stationery. Search by keyword or...
🛒 Idealo.de
Scrape Idealo.de products with identity details, GTIN, price ranges, specifications...

👉 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.