Willhaben.at Real Estate Scraper
Pricing
from $3.50 / 1,000 results
Willhaben.at Real Estate Scraper
Austria real estate scraper for Willhaben.at β apartments, houses, land & commercial, rent or sale β with province filters and built-in delta mode.
Pricing
from $3.50 / 1,000 results
Rating
0.0
(0)
Developer
Artsiom Kunitsyn
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
willhaben-scraper
Scrapes real estate listings from Willhaben.at (apartments, houses, land, commercial β rent or sale) via Willhaben's own internal JSON search API, not HTML scraping.
Contents
- Key features
- Output
- Input
- Input examples
- Incremental (delta) mode
- How to scrape Willhaben.at
- How much does it cost
- You might also like
- FAQ
π Key features
- Real-estate specialist, not a jack-of-all-trades. Built for Willhaben's real-estate categories specifically, rather than spreading thin across cars, jobs, and marketplace listings too.
- No URL wrangling. Pick a category and an Austrian province from a dropdown β no need to construct or paste a Willhaben search URL yourself.
- Delta mode built in. Every run classifies each listing as
new,changed,unchanged, ordelistedagainst a persisted baseline. Run it on a schedule and you're not paying for a full re-scrape every time β just what actually changed. It's also what makes price-history tracking possible at all. - Full category coverage, including the categories many scrapers skip β land/plots and commercial, not just apartments.
- Privacy-aware by construction.
agency_nameis populated for professional listings only (company name) and leftnullfor private sellers β no private-seller personal data leaves the dataset.
π Output
One dataset item per listing, with a normalized schema (see
.actor/dataset_schema.json for the full field list) plus a
change_type field: new, changed, unchanged, or delisted (see
Incremental mode below).
Example job record:
{"source": "willhaben","external_id": "1234567890","url": "https://www.willhaben.at/iad/immobilien/d/mietwohnungen/wien/wien-1220-donaustadt/...","country": "AT","state": "Wien","district": "Donaustadt","city": "Wien","postal_code": "1220","latitude": 48.2333,"longitude": 16.4667,"price_eur": 1450.0,"price_per_sqm_eur": 19.33,"living_area_sqm": 75.0,"estate_size_sqm": 75.0,"rooms": 3,"listing_type": "rent","property_class": "apartment","property_type": "Wohnung","has_balcony": true,"has_garden": false,"has_parking": false,"agency_name": "Muster Immobilien GmbH","published_at": "2026-08-01T09:12:00.000Z","change_type": "new"}
Every record also carries condition, year_built, and energy_class β omitted from the example
above because they're currently always null (see known gap below).
Results can be downloaded as JSON, CSV, or Excel from the Console's Output tab, or pulled via the Apify API/dataset endpoint.
Known gap: condition, year_built, and energy_class are always null β Willhaben's search
API doesn't carry them, and the one endpoint that does blocks both plain and TLS-impersonated
requests.
βοΈ Input
See .actor/input_schema.json for the full JSON schema. Key parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
category | String (required) | β | One of 7 categories: apartment_rent, apartment_sale, house_rent, house_sale, land, commercial_rent, commercial_sale. |
region | String | all | One of Austria's 9 provinces (e.g. wien, steiermark), or all for the whole country. Changing this between runs starts a fresh incremental-mode baseline for the category. |
mode | String | auto | auto (recommended): full scan on the first run, incremental after. full: always push every listing and refresh the baseline. incremental: always push only new/changed listings. See Incremental mode. |
maxItems | Integer | 50 | Stop after pushing this many dataset items. Defaults to a fast, cheap preview (also what keeps an unconfigured run within Apify's automated 5-minute QA check). Raise it or clear it (set to null) for a full run β note a capped run never updates the incremental baseline (see below), so any real tracking run needs this cleared. |
maxPages | Integer | (none) | Safety cap on search pages fetched. A capped run can't detect delistings and won't update the incremental baseline. |
rows | Integer | 200 | Listings per search page (1β200). |
delaySeconds | Number | 3.5 | Politeness delay between consecutive search-page requests. |
proxyConfiguration | Object | {"useApifyProxy": false} | Apify Proxy config. Off by default β confirmed by testing that Willhaben returns HTTP 403 to Apify's shared datacenter proxy pool, while a direct connection works fine. Only reach for proxy (residential, not datacenter) if you start seeing blocks. |
impersonate | String | (none) | Optional curl_cffi TLS-impersonation target (e.g. chrome124), used only if Willhaben starts blocking plain requests. |
π§ͺ Input examples
Quick preview β Wien apartments for rent, default 50-item cap:
{"category": "apartment_rent","region": "wien"}
Full-country scan β every land/plot listing in Austria, capped for a quick preview:
{"category": "land","region": "all","maxItems": 100}
Scheduled tracking run β full, uncapped run (maxItems cleared β required for the baseline to
save and delistings to be detected, see Incremental mode):
{"category": "apartment_rent","region": "wien","mode": "incremental","maxItems": null}
π Incremental (delta) mode
Every run classifies each listing as new, changed (price moved), unchanged, or delisted,
using a state baseline persisted in a named Apify Key-Value Store scoped to category + region.
mode: auto(default) β first run for a scope pushes everything (full); later runs push onlynew/changed/delisted(incremental).- Recommended setup: schedule a frequent Task on
auto, plus a periodic (e.g. weekly) Task explicitly onmode: fullto force a full resync β a page-capped or otherwise partial run never updates the baseline or reports delistings, so a periodic full run keeps the baseline honest.
Full design: ../../docs/incremental-mode.md.
π How to scrape Willhaben.at
- Open the Willhaben.at Real Estate Scraper in Apify Console and go to the Input tab.
- Pick a category (e.g. "Apartments β rent") and a region (e.g. "Wien"), or leave region at "All of Austria" for full country coverage.
maxItemsdefaults to 50 (a quick preview) β clear it (set tonull) along withmaxPagesfor a full, uncapped run.- Click Start.
- When the run finishes, browse results in the Output tab, or download as JSON/CSV/Excel, or fetch them via the API.
- To track a market over time instead of scraping once: create a Schedule with
mode: autoβ the first run does a full scan, every run after only bills the listings that actually changed.
π° How much does it cost
Pricing: $3.50 per 1,000 results (pay-per-result), plus a fixed, negligible per-run start fee. No cost for pages that return zero results.
Example: a full scan of Wien apartment-rent listings (~4,700 listings, confirmed by a real
test run) costs roughly $16.40 for the initial full scan. Because of built-in delta mode, a
scheduled re-run afterwards only bills for listings that are actually new, changed, or
delisted β not the full ~4,700 again β so ongoing monitoring costs a fraction of the initial
scan once the baseline is established.
π You might also like
- ImmoScout24 (AT) Real Estate Scraper β a second, independent Austrian real-estate source with the identical output schema by design, so results from both merge directly for cross-checking coverage or de-duplicating listings posted on both sites.
- Willhaben.at Vehicles Scraper β the sibling actor for Willhaben's other big vertical: used cars, motorcycles, commercial vehicles, and caravans/motorhomes. Same delta-mode design, same province filters β useful if you're tracking a seller or household's full footprint on Willhaben, not just real estate.
β FAQ
Is it legal to scrape Willhaben.at? It's legal to collect publicly available listing data such as prices, descriptions, and locations. Results may contain limited personal data (agency names for professional listings only β see Key features); scrape it only with a legitimate purpose under GDPR.
How do I get only new/changed listings? Use mode: auto (or incremental) on a schedule β see
Incremental mode.
Why is a field always null for some listings? condition, year_built, and energy_class
are always null β see Output for why.
Search keywords
willhaben scraper, willhaben.at scraper, austria real estate scraper, austrian property scraper, immobilien scraper, wien real estate data, apartment scraper austria, house scraper austria, willhaben api, willhaben immobilien api, real estate delta scraper, real estate price tracking, austria property data feed