Willhaben.at Scraper - Listings, Prices, Sellers & 40+ Fields avatar

Willhaben.at Scraper - Listings, Prices, Sellers & 40+ Fields

Pricing

from $1.00 / 1,000 results

Go to Apify Store
Willhaben.at Scraper - Listings, Prices, Sellers & 40+ Fields

Willhaben.at Scraper - Listings, Prices, Sellers & 40+ Fields

From $1/1K. Scrape Willhaben.at listings into clean JSON with 40+ structured fields, including prices, GPS coordinates, photos, dates, seller details and category-specific attributes. Search with filters or paste any Willhaben URL.

Pricing

from $1.00 / 1,000 results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

0

Bookmarked

6

Total users

0

Monthly active users

16 days ago

Last modified

Share

Willhaben.at Scraper: Cars, Property, Marketplace & Job Listings

Willhaben.at Scraper turns Austria's largest online marketplace into clean, structured JSON. Pull used cars, apartments and houses, land, general marketplace goods, and job postings straight from willhaben's own data source, with roughly 40 base fields per listing (often many more once every category attribute is flattened in), GPS coordinates, a full address hierarchy, and every photo URL. Build a search from filters, or paste any willhaben search-page link, 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 listings. Build a search from filters (category, keyword, price range, area, sort), or paste any willhaben search-page link. URL mode accepts multiple links at once and walks every result page forward automatically.
  • Nine categories in one actor. Marketplace goods, apartments and houses to rent or buy, land, used cars, caravans and motorhomes, and jobs, each returning its own category-specific fields.
  • Roughly 40 base fields per listing, plus every category-specific attribute flattened into attr_* keys and the original attribute array preserved, so nothing the site exposes is dropped.
  • Full location detail on every record. GPS latitude and longitude, the complete address hierarchy (state, district, postcode, municipality), and every photo URL.
  • Optional detail-page enrichment adds contact name, dealer or organisation info, address detail and the complete attribute set; detail pages are fetched concurrently across listings rather than one at a time.
  • Automatic forward pagination with page-level de-duplication and a mid-run checkpoint, so an interrupted run can pick up where it left off instead of re-collecting, and re-charging, listings it already pushed.
  • Built for schedules. Incremental mode tracks a search over time and returns only new and changed listings on recurring runs, and a run that cannot reach willhaben at all ends with a clear status message explaining why, instead of a silent empty result.

Use Cases

  • Car buyers and dealers: track new listings for a specific make, model, year range or mileage band across Austria, or within one region.
  • Real estate investors and renters: monitor apartments, houses and land in a chosen area for new listings and price changes.
  • Resellers and marketplace watchers: search marketplace categories by keyword to spot newly listed items in a price range.
  • Job seekers and recruiters: track new postings for a role or keyword, with company, salary and employment-type fields.
  • Market researchers and analysts: build historical pricing and inventory datasets across categories for trend analysis.

Data You Get

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

FieldExample
id"000000001"
urlhttps://www.willhaben.at/iad/gebrauchtwagen/d/auto/sample-000000001/
title"Sample Listing Title"
description"Full listing description text appears here."
price / priceDisplay7800 / "€ 7.800"
category"gebrauchtwagen/auto/gebrauchtwagenboerse"
state / district / postcode"Wien" / "Wien" / "1010"
locationName"Sample Location"
latitude / longitude48.2000 / 16.3700
publishedDate / changedDate"2026-01-01T00:00:00.000Z"
isPrivate / advertiserLabeltrue / "Privat"
imageCount / mainImage12 / https://cache.willhaben.at/mmo/0/000/000/000_0.jpg
images["https://cache.willhaben.at/mmo/0/000/000/000_0.jpg", ...]
make / model / year / mileagecar fields: "SampleMake" / "SampleModel" / 2019 / 120000
fuel / transmission"Benzin" / "Automatik"
rooms / livingArea / floorproperty fields: 3.5 / 85 / "2"
pricePerSqm4200.0 (property listings)
contactName / organisationName"A. B." / "Sample Dealer" (only when Fetch detail pages is on)
seoUrl"gebrauchtwagen/d/auto/sample-000000001/"
advertiserInfothe seller block the search API returns, passed through as-is
rawAttributesthe full, unflattened list of {name, values} attribute objects for this listing

Every attribute willhaben exposes for a listing is also flattened into its own attr_* key (for example attr_CAR_MODEL_MAKE, attr_NUMBER_OF_ROOMS), so a field this table does not name is still in the record under its raw attribute name. Jobs listings (category jobs) are a different record shape entirely: id, url, category ("jobs"), title, position, companyName, companyId, companyLogo, locations, locationName, salary, salaryTimeFrame, employmentTime, employmentModes, publishedDate, createdDate, modifiedDate, isExpired, topJob, overpay, brandNew, internalApplication, and raw (the complete source entry); the Jobs category also ignores the price and area filters.

How to Use

  1. Pick a mode: search builds a query from the filters below, url scrapes any willhaben search-page link you paste.
  2. In search mode, choose a category and fill in the filters you need (keyword, price range, area, sort). In URL mode, paste one or more search-page links; filter fields are ignored.
  3. Turn on Fetch detail pages if you want contact and dealer info, and set Max listings (and optionally Max pages) to control run size and cost.
  4. Click Start. Download the dataset as JSON, CSV or Excel, or read it through the API.

Search used cars, list-only:

{
"mode": "search",
"category": "gebrauchtwagen/auto/gebrauchtwagenboerse",
"maxListings": 20,
"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "AT" }
}

Search the marketplace by keyword with a price range:

{
"mode": "search",
"category": "kaufen-und-verkaufen/marktplatz",
"keyword": "iphone",
"minPrice": 100,
"maxPrice": 500,
"sort": "price-asc",
"maxListings": 200,
"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "AT" }
}

Rentals in Vienna with detail enrichment:

{
"mode": "search",
"category": "immobilien/mietwohnungen",
"areaId": 900,
"fetchDetails": true,
"maxListings": 50,
"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "AT" }
}

Paste willhaben search URLs (multi-URL, forward pagination):

{
"mode": "url",
"urls": [
"https://www.willhaben.at/iad/immobilien/eigentumswohnung/wien",
"https://www.willhaben.at/iad/gebrauchtwagen/auto/gebrauchtwagenboerse?YEAR_MODEL_FROM=2018"
],
"maxPages": 5,
"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "AT" }
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/willhaben-at-scraper").call(run_input={
"mode": "search",
"category": "gebrauchtwagen/auto/gebrauchtwagenboerse",
"maxListings": 20,
"proxy": {"useApifyProxy": True, "apifyProxyGroups": ["RESIDENTIAL"], "apifyProxyCountry": "AT"},
})
for listing in client.dataset(run["defaultDatasetId"]).iterate_items():
print(listing["title"], listing["priceDisplay"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/willhaben-at-scraper').call({
mode: 'search',
category: 'gebrauchtwagen/auto/gebrauchtwagenboerse',
maxListings: 20,
proxy: { useApifyProxy: true, apifyProxyGroups: ['RESIDENTIAL'], apifyProxyCountry: 'AT' },
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

Result caps and Max pages

Max listings caps the total number of records returned across every search or URL in one run (0 for unlimited). Max pages optionally caps how many result pages are walked per search or URL (about 25 listings per page for most categories, 90 for Jobs); leave it empty to walk every result page the site serves.

Resume and recurring updates

  • Resume (resumeFromRunId) continues one specific interrupted run: paste its run or dataset ID and this run skips every listing that run already collected, matched on the same id field, so you don't pay twice.
  • Incremental mode (incrementalMode) is for running the same search again and again, for example daily. The first run for a given search returns everything as NEW. Later runs return NEW and UPDATED (with changedFields) by default; UNCHANGED listings are suppressed, neither returned nor billed, unless emitUnchanged is on. EXPIRED is only produced after a run that fully scans the tracked search (not capped by maxListings, not a Resume run), and only when emitExpired is on. REAPPEARED only appears for a listing that an earlier complete-scan run with emitExpired on had recorded as gone. State is kept separately per search/category/URL/filter combination unless you set stateKey to name or deliberately share it. With incremental mode off, output is exactly as before.

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 haven't 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 builds a query from the filters below; url scrapes pasted search-page links.
categorystringkaufen-und-verkaufen/marktplatzSection of willhaben.at to scrape (Search mode). Includes Jobs, which returns job-specific fields and ignores the price and area filters.
categoryPathstringnoneAdvanced: override Category with any willhaben SEO path. Leave empty to use Category above.
keywordstringnoneFree-text keyword within the category. Leave empty to list everything in the category.
areaIdintegernonewillhaben location ID to restrict results to a region or district, for example 900 for Vienna. Not applied to the Jobs category.
minPriceintegernoneMinimum price filter, in euros. Not applied to the Jobs category.
maxPriceintegernoneMaximum price filter, in euros.
sortstringdefaultOne of default, newest, price-asc, price-desc. The price-based sorts do not apply to the Jobs category.
customParametersarraynone (prefill: empty list)Extra raw willhaben query parameters as KEY=VALUE strings, one per line, for example YEAR_MODEL_FROM=2018.
urlsarraynone (prefill: one example search URL)willhaben search-page URLs to scrape (URL mode). Multiple URLs are supported; filter fields above are ignored in this mode.
fetchDetailsbooleanfalseOpen each listing's detail page to add contact name, dealer or organisation info, address detail and the full attribute set. Costs an extra fetch per listing.
maxListingsinteger20Maximum number of listings to scrape across all searches. Set 0 for unlimited.
maxPagesintegernone (omitted or 0 means walk every result page)Optional bound on result pages walked per search or URL.
resumeFromRunIdstringnonePaste a previous run ID (or dataset ID) from this actor to skip listings already collected there. For recurring monitoring of the same search, use incrementalMode instead.
incrementalModebooleanfalseTurn on for recurring monitoring of the same search. See the Resume and recurring updates section above for exactly what each run returns.
stateKeystringnoneName this monitoring campaign to keep its state stable, or to deliberately share state across differently-configured runs. Leave empty to derive a key automatically from the search/category/URL/filter settings.
emitUnchangedbooleanfalseIncremental mode only: also return, and bill, listings unchanged since the last run, marked UNCHANGED.
emitExpiredbooleanfalseIncremental mode only: also return, and bill, listings from a previous run no longer found, marked EXPIRED. Only produced after a run that fully scanned the tracked search, not one capped by maxListings and not a Resume run.
proxyobjectnone (prefill: Apify Proxy, Residential group, country AT)Connection settings. willhaben.at rejects non-residential connections; see Plan Requirement below.
mcpConnectorsarraynoneOptional: send a summary of each listing to apps you authorized under Integrations.
notionParentPageUrlstringnoneNotion connector only: page under which item pages are created.
maxNotifyListingsinteger50Cap on items written to each connector per run. Does not affect the dataset.

Output Example

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

{
"id": "000000001",
"uuid": "00000000-0000-0000-0000-000000000000",
"url": "https://www.willhaben.at/iad/gebrauchtwagen/d/auto/sample-000000001/",
"title": "Sample Listing Title",
"description": "Full listing description text appears here.",
"price": 7800,
"priceDisplay": "€ 7.800",
"category": "gebrauchtwagen/auto/gebrauchtwagenboerse",
"make": "SampleMake",
"model": "SampleModel",
"mileage": 120000,
"year": 2019,
"fuel": "Benzin",
"transmission": "Automatik",
"condition": "Gebrauchtwagen",
"country": "Österreich",
"state": "Wien",
"district": "Wien",
"postcode": "1010",
"locationName": "Sample Location",
"latitude": 48.2000,
"longitude": 16.3700,
"publishedDate": "2026-01-01T00:00:00.000Z",
"changedDate": "2026-01-01T00:00:00.000Z",
"isPrivate": true,
"advertiserLabel": "Privat",
"imageCount": 2,
"mainImage": "https://cache.willhaben.at/mmo/0/000/000/000_0.jpg",
"images": [
"https://cache.willhaben.at/mmo/0/000/000/000_0.jpg",
"https://cache.willhaben.at/mmo/0/000/000/000_1.jpg"
]
}

Plan Requirement

willhaben.at accepts traffic only from Austrian, or nearby EU, residential connections; connections from typical datacenter ranges are rejected outright. Use an Apify plan that includes the Residential proxy group, and leave the Proxy input at its default prefill (Residential, country AT) or set it yourself. The actor rotates between Austrian and German residential exits automatically, and automatically retries with a different connection when one is refused. If every attempt is still rejected, the run logs a clear warning explaining the fix rather than quietly returning an empty dataset that looks like a clean success.

FAQ

How much does it cost?

You pay per record returned, with detail-page enrichment billed as a separate per-listing surcharge only when Fetch detail pages is on. The Pricing tab on the actor page shows current rates. Use Max listings (and optionally Max pages) to cap the cost of any run.

This actor collects only publicly available listing data. You are responsible for how you use it: follow willhaben's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Contact details and photos may carry their own rights beyond simple facts like price or location.

Can I get only new or changed listings on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only NEW and UPDATED listings for that search by default, and unchanged ones are not billed.

What is the difference between Resume and Incremental mode?

Resume from run ID continues one specific interrupted run: paste its run or dataset ID and this run skips every listing that run already collected. Incremental mode is for running the same search again and again, for example daily, and getting only what changed; it keeps its own state per search/category/URL/filter combination (or per State key, if you set one) instead of needing a run ID pasted in every time.

Do REAPPEARED and EXPIRED listings always show up in incremental mode?

No. EXPIRED is only produced after a run that fully scans the tracked search with Emit expired on; a run capped by Max listings, or a Resume run, cannot tell "gone" apart from "not reached yet", so expiry detection is skipped for that run and the previous state is kept as-is. REAPPEARED only appears for a listing that an earlier run had already marked EXPIRED under those conditions. If you have never turned on Emit expired, your incremental runs will only ever show NEW and UPDATED (plus UNCHANGED if you turn that on).

Why did my run fail instead of returning an empty dataset?

A run fails outright only in specific cases: a Resume from run ID pointing to a run or dataset ID the actor cannot read, or Incremental mode combined with Resume against a search that already has saved incremental state (remove one, or use a different State key). Otherwise, a run that finds nothing still succeeds, returning 0 items with a status message explaining why, most often a missing or rejected connection, so "nothing found" is never confused with "the run crashed".

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 a summary of each listing into Notion, Linear or Airtable.

🔗 Want more car data?

Pair this actor with these related scrapers from the same team:

🏷️ Mudah.my Cars, Property, Jobs & Marketplace Scraper
Scrape Mudah.my listings across every category: cars, motorcycles, property, mobiles...
🏷️ Subito.it
Scrape Subito.it listings across cars, real estate, marketplace, jobs, and more. Search...
🏷️ Gumtree UK
Scrape gumtree.com classifieds across motors, property, jobs, services, pets and goods...
🚗 Trade Me NZ Scraper
Scrape trademe.co.nz across all five sections: Marketplace goods and auctions, Property...
🚗 Marktplaats.nl Scraper
From $1/1K. Scrape Marktplaats.nl listings by keyword or URL. Extract title, price...
🚗 Autotrader US
Scrape US car listings from Autotrader by make, model, ZIP, price, year, body style...

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