Willhaben.at Scraper — Austrian Property Listings, Photos, Geo avatar

Willhaben.at Scraper — Austrian Property Listings, Photos, Geo

Pricing

from $1.49 / 1,000 listings

Go to Apify Store
Willhaben.at Scraper — Austrian Property Listings, Photos, Geo

Willhaben.at Scraper — Austrian Property Listings, Photos, Geo

Scrape Willhaben.at property listings across Austria - Vienna, Graz, Linz, Salzburg, Innsbruck and every other city. 32 fields per listing: price, price per m2, area, rooms, floor, full geo with coordinates, agency, and up to 3 preview photo URLs.

Pricing

from $1.49 / 1,000 listings

Rating

0.0

(0)

Developer

Anatoly Skuba

Anatoly Skuba

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

3 days ago

Last modified

Categories

Share

Scrape property listings from Willhaben.at, the largest marketplace in Austria — apartments, houses and plots, for sale and for rent, in Vienna, Graz, Linz, Salzburg, Innsbruck and every other Austrian town.

32 fields per listing, including latitude and longitude, price per m², floor, agency and up to three preview photo URLs. No login, no cookies, no browser needed.

Empty results, and why you will not get them here

A scraper built on CSS selectors fails quietly. When Willhaben changes its markup, or answers an automated request with a block page, you do not get an error — you get an empty table, or a column of empty values, and you find out later.

This Actor is built the other way round:

  • it reads the data Willhaben already renders into the page, so a redesign of the visual layout does not change what it returns;
  • it goes through residential proxies with polite delays and retries every page;
  • at the end of every run it prints how many pages failed and how many rows it skipped, and warns you when a promised field came back mostly empty. You never have to guess whether the file is complete;
  • you pay per listing returned. A run that finds nothing costs you the Actor start fee of $0.00005 and nothing else.

Quick Start

  1. Open willhaben.at, set your filters
  2. Copy the address of the results page (not a single listing)
  3. Paste it into searchUrls and press Start

The default input works out of the box: apartments for sale across Austria.

{
"searchUrls": ["https://www.willhaben.at/iad/immobilien/eigentumswohnung/eigentumswohnung-angebote"],
"maxItems": 1000
}

Why this one does not break

Most scrapers read the rendered page with CSS selectors. When the site changes its markup, they silently return nothing.

This Actor reads the data the server already renders into the page as structured JSON. There are no CSS selectors anywhere in the code. The listing array is located by its shape — the set of fields every record must have — rather than by a fixed path, so a framework upgrade that moves the data does not break extraction.

Two more consequences:

  • No browser. Plain HTTP requests, so runs are fast and compute is cheap
  • Typed fields. Numbers arrive as numbers, dates as ISO timestamps, coordinates as two separate numbers

A failed page is retried three times with backoff and never aborts the run. A malformed listing is skipped, not the page around it. Every run writes a RUN_STATS record with the real failure rate — you can audit it yourself.

Output

One row per listing:

FieldNotes
id, urlStable listing id and direct link
typeWohnung, Haus, Grundstück, … as the portal labels it
titleListing headline
price, currency, marketingTypeEUR. marketingType is BUY or RENT — rental search URLs work too, and there price is the monthly rent
priceForDisplayPrice exactly as the portal shows it
pricePerSqmTaken from the portal, or calculated when missing
livingSpace, terrainArea
rooms, floorNumbers, not strings
street, postcode, city, district, provinceFull Austrian geo. Vienna is split properly: city is Wien, district is 13. Bezirk, Hietzing
latitude, longitudeWGS84, ready for a map or a spatial join
countryISO 3166-1 alpha-2 — AT for Austrian listings, and the real code for the foreign ones Willhaben carries
realtorCompany, realtorIdAgency — see below
isPrivateOwner, sellerLabelWhether the seller is a private person
statusAdvert status as the portal reports it
imageUrls, imagesCountFull-size photo URLs — up to 3 per listing, see below
publishedAtThe timestamp the portal shows — not the first publication date, see below
daysOnMarketDays since publishedAt, with the same caveat
sourceUrl, scrapedAt

Two limits I would rather you knew before you buy

Photos: up to three per listing. This Actor reads the structured data the search page already carries, which is why it is fast and cheap and does not need a browser. That page carries at most three preview images per advert. Measured on 1,500 listings on 1 September 2026: 1,471 had exactly 3. If you need every photo of a flat, you need a scraper that opens each advert page, and it will cost you roughly one request per listing instead of one per thirty.

publishedAt is the portal's timestamp, not the first publication date. Sellers on Willhaben can push an advert back to the top of the list, and the portal then shows the new time. In that same 1,500-listing sample every timestamp fell inside one 5½-hour window, every one landed exactly on a quarter hour, and daysOnMarket was 0 in all 1,500 rows. Fifteen hundred genuinely new Austrian flats in five and a half hours is not plausible. So read this field as "last time the seller pushed it up" and do not build a time-on-market analysis on it.

I would rather lose a sale here than have you find this out after paying.

The three things that go wrong with property scrapers

These are the complaints you will find under other property scrapers in this Store.

"It stopped working." This Actor reads the structured data the server already puts inside the page, not CSS selectors, so a visual redesign does not break extraction. A health check runs every morning, so a real break is found before a customer runs into it.

"Not fetching all records." Every page is retried, and the retry covers parsing, not just the network. The run reports its own failure rate in RUN_STATS: if any page was lost you will see it, instead of quietly getting a shorter file.

"Unexpected billing." You are charged per listing written to the dataset, not per request. maxItems is a hard stop. Turn on skipWithoutPrice and listings with an empty price are dropped before billing.

No personal data

This Actor does not return the seller's personal contact — no name, no phone number, no email, no private address. For private sellers the agency field stays empty and only a flag is set. Agency names and the portal's advertiser id are company data, not personal data, and are returned.

Limits — what this Actor does not do

  • It reads search result pages, not individual listing pages. Fields that only exist on the detail page (full description, floor plans, energy certificate) are not returned
  • It does not log in and does not see anything a logged-out visitor cannot see
  • terrainArea is only present where the portal publishes it

Pricing

$1.49 per 1,000 listings — $0.00149 per listing — plus $0.00005 per Actor start. Platform usage (compute and proxy) is included in that price and is not billed to you separately.

A run that returns nothing costs nothing beyond the Actor start.

Cost control

Set Max listings before you press Start and the run's cost is fixed in advance: 1,000 listings is $1.49, 250 listings is $0.37. The Actor stops exactly at that number, on every plan, and writes a RUN_STATS record with what it actually did. Nothing here depends on your plan tier — the behaviour on the Free plan is the same as on any other, just bounded by the credit the plan gives you.

Development

Offline tests, no network needed:

$npm test