# Willhaben Scraper – Real Estate, Cars, Marketplace & Jobs (`ninhothedev/willhaben-scraper`) Actor

Scrape willhaben.at, Austria's #1 classifieds: apartments, houses, land, cars, motorcycles, marketplace items and jobs. Prices, m², rooms, GPS, seller, photos. Fast HTTP, no login.

- **URL**: https://apify.com/ninhothedev/willhaben-scraper.md
- **Developed by:** [ninhothedev](https://apify.com/ninhothedev) (community)
- **Categories:** Real estate, E-commerce, Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Willhaben Scraper – Real Estate, Cars, Marketplace & Jobs

Scrape **willhaben.at**, Austria's biggest classifieds site, across **every vertical** with one actor: **apartments and houses for rent or sale, land, commercial property, used cars, motorcycles, vans, caravans, Marktplatz items and jobs**. You get clean, flat rows with **price, m², rooms, €/m², address, postcode, district, Bundesland, GPS coordinates, seller type and name, photos and publish date**, plus vertical fields like **make, model, year, mileage, fuel and kW/PS** for vehicles or **company, salary and employment type** for jobs. Export to JSON, CSV or Excel, or send it to your CRM, Google Sheets or database.

Built for real-estate investors, agents, proptech and car-trading startups, recruiters and market analysts who need fresh Austrian listings every day.

- ✅ **All willhaben verticals:** Immobilien, Gebrauchtwagen/Motorrad, Marktplatz, Jobs
- ✅ **Search by fields** (category, Bundesland, Bezirk, town or postcode, keyword, price, area, rooms, make, year, mileage, seller type) **or paste any willhaben.at URL** with your filters already set
- ✅ **Fast and cheap:** reads willhaben's own JSON data (up to 200 listings per request) with plain HTTP, so no browser and no proxy are needed
- ✅ **Newest first** and an **"only listings from the last X hours"** filter for daily monitoring and alerts
- ✅ Optional **full details:** complete description, all photos, every attribute (heating, energy class (HWB), condition, equipment), category path, agency or dealer phone and website, first-published and expiry dates
- ✅ Pay only per listing. No willhaben account or API key needed.

### What data can you extract from willhaben.at?

| Field | Example |
|---|---|
| `id`, `url` | 1890468385, https://www.willhaben.at/iad/immobilien/d/eigentumswohnung/… |
| `vertical`, `category` | real_estate / vehicles / marketplace / jobs, "Apartment for sale" |
| `title`, `description` | Charmante Etagenwohnung mit Fernblick … |
| `price`, `price_text`, `currency` | 280000, "€ 280.000", EUR |
| `price_per_sqm` | 3835.62 |
| `address`, `location`, `postcode`, `district`, `state` | Friedrich Schiller-Straße, Mödling, 2340, Mödling, Niederösterreich |
| `latitude`, `longitude` | 48.0847, 16.2888 |
| `published_at`, `updated_at` | 2026-10-15T15:56:03+00:00 |
| `seller_type`, `seller_name`, `seller_id` | commercial, PRADIUM Immobilien GmbH & Co KG, 1003856 |
| `image_url`, `image_urls`, `image_count` | All photo URLs in full size |
| **Real estate:** `property_type`, `transaction`, `rooms`, `area_sqm`, `living_area_sqm`, `usable_area_sqm`, `plot_area_sqm`, `floor`, `outdoor_area` | Wohnung, sale, 3.5, 73, 73, 73, null, null, Loggia |
| **Vehicles:** `make`, `model`, `model_variant`, `year`, `mileage_km`, `fuel`, `power_kw`, `power_hp`, `transmission`, `body_type`, `condition`, `owners` | BMW, 3er-Reihe, 320d Sportline, 2021, 75750, Diesel, 140, 190, Schaltgetriebe, Limousine, Gebrauchtwagen, 1 |
| **Jobs:** `company_name`, `salary`, `salary_period`, `employment_type`, `position`, `apply_url` | ACTIEF JOBMADE GmbH, 3000, monatlich, Vollzeit, Mitarbeiter:in |
| **Details:** `category_path`, `features`, `attributes`, `construction_year`, `heating`, `energy_hwb`, `contact_name`, `company_phone`, `company_website`, `company_address`, `first_published_at`, `expires_at` | Immobilien > Wohnung kaufen > Niederösterreich > Mödling, … |

Every row has the same columns. Fields that don't apply to a vertical are `null`, which keeps CSV and Excel exports tidy.

### How to scrape willhaben.at

1. **Pick what to scrape**, e.g. *Real estate – Apartments for rent*, *Vehicles – Cars*, *Marketplace* or *Jobs*.
2. Optionally set a **location** (`Wien`, `Steiermark`, `Linz Land`, `Graz`, `1100`, or several separated by commas), a **keyword** and filters such as price, m², rooms, make, year or mileage. Set **Max listings**.
   *Or* set up a search on willhaben.at in your browser and paste the URL into **Search URLs**. Any category works, and all URL filters are kept.
3. Click **Start**, then download the results as JSON, CSV or Excel or fetch them via the API.

```json
{
  "vertical": "mietwohnungen",
  "location": "Wien",
  "priceMax": 1500,
  "roomsMin": 2,
  "maxItems": 200,
  "includeDetails": true
}
```

More examples:

```json
{ "vertical": "auto", "make": "BMW", "yearMin": 2018, "mileageMax": 100000, "location": "Oberösterreich", "sellerType": "private" }
{ "vertical": "marktplatz", "keyword": "iPhone 15", "location": "Steiermark", "priceMin": 200 }
{ "vertical": "jobs", "keyword": "Buchhaltung", "location": "Wien" }
{ "searchUrls": ["https://www.willhaben.at/iad/immobilien/haus-kaufen/steiermark/graz"], "maxAgeHours": 24 }
```

### Output example

Real output from a test run (apartment for sale in Mödling, with details; the description and photo list are shortened here):

```json
{
  "id": "1890468385",
  "url": "https://www.willhaben.at/iad/immobilien/d/eigentumswohnung/niederoesterreich/moedling/charmante-etagenwohnung-mit-fernblick-lift-neue-fenster-zentrumslage-1890468385/",
  "vertical": "real_estate",
  "category": "Apartment for sale",
  "title": "Charmante Etagenwohnung mit Fernblick: Lift, neue Fenster, Zentrumslage",
  "description": "Diese gepflegte 3,5-Zimmer-Wohnung mit rund 73 m² überzeugt mit einem durchdachten, großzügigen Grundriss …",
  "price": 280000,
  "price_text": "€ 280.000",
  "currency": "EUR",
  "price_per_sqm": 3835.62,
  "location": "Mödling",
  "postcode": "2340",
  "district": "Mödling",
  "state": "Niederösterreich",
  "country": "Österreich",
  "latitude": 48.08473782,
  "longitude": 16.28880622,
  "published_at": "2026-10-15T15:56:03+00:00",
  "updated_at": "2026-10-15T16:00:26+00:00",
  "seller_type": "commercial",
  "seller_name": "PRADIUM Immobilien GmbH & Co KG",
  "seller_id": "1003856",
  "image_url": "https://cache.willhaben.at/mmo/5/189/046/8385_-1190275888.jpg",
  "image_urls": ["https://cache.willhaben.at/mmo/5/189/046/8385_-1190275888.jpg", "…"],
  "image_count": 10,
  "property_type": "Wohnung",
  "transaction": "sale",
  "rooms": 3.5,
  "area_sqm": 73,
  "living_area_sqm": 73,
  "usable_area_sqm": 73,
  "construction_year": 1959,
  "heating": "Etagenheizung",
  "energy_hwb": 110,
  "category_path": "Immobilien > Wohnung kaufen > Niederösterreich > Mödling",
  "features": ["Abstellraum", "Einbauküche", "Fahrstuhl", "Keller"],
  "attributes": { "Zustand": "Sehr gut/Gut", "Verfügbarkeit": "ab sofort", "Heizung": "Etagenheizung", "Böden": "Parkett", "ENERGY_HWB_CLASS": "D" },
  "first_published_at": "2026-08-20T15:56:03+00:00",
  "expires_at": "2027-08-14T22:00:00+00:00",
  "company_phone": "0043 664 866 2666",
  "status": "active",
  "details_scraped": true
}
```

A used car from the same test (search results only, no details):

```json
{
  "id": "1953363645",
  "vertical": "vehicles",
  "category": "Car",
  "title": "BMW 3er-Reihe 320d SPORTLINE/AHK/PANO/18\"/TEILLEDER/ALARM/1.B...",
  "price": 27980,
  "location": "Wels",
  "postcode": "4600",
  "state": "Oberösterreich",
  "seller_type": "commercial",
  "seller_name": "Automobile Händlhuber",
  "image_count": 89,
  "make": "BMW",
  "model": "3er-Reihe",
  "year": 2021,
  "mileage_km": 75750,
  "fuel": "Diesel",
  "power_kw": 140,
  "power_hp": 190,
  "transmission": "Schaltgetriebe",
  "body_type": "Limousine"
}
```

### Pricing

**Pay per result: $1.50 per 1,000 listings** (plus a tiny actor-start fee). Detail enrichment costs the same per listing.

| Listings | Cost |
|---|---|
| 100 | ≈ $0.15 |
| 1,000 | ≈ $1.50 |
| 10,000 | ≈ $15 |

Runs are fast and light (256–1024 MB RAM is enough). You can set a maximum cost per run in Apify, and the actor stops when it reaches it.

### Use cases

- **Real-estate investors and agents:** track new Vienna rentals or Styrian houses every morning, compare €/m² by Bezirk and spot underpriced listings first.
- **Market analytics and proptech:** build rent and price indices for Austria by postcode, room count and property type, using GPS coordinates for maps.
- **Car dealers and leasing companies:** monitor private used-car offers by make, year and mileage for sourcing and price benchmarking.
- **E-commerce and resellers:** follow Marktplatz prices for electronics, bikes or furniture, and find private sellers to buy from.
- **Recruiters and HR tech:** collect willhaben job ads with company, salary and employment type for lead generation and salary benchmarks.
- **Lead generation:** list agencies (Makler), car dealers and shops with their phone, website and address (details mode, commercial sellers only).

### Integrations

Use the results anywhere: the **Apify API**, **Make**, **Zapier**, **n8n**, **Google Sheets**, **Airbyte**, **Slack** and **webhooks**. Schedule the actor (for example daily with `maxAgeHours: 24`) to get only new listings.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("ninhothedev/willhaben-scraper").call(run_input={
    "vertical": "mietwohnungen", "location": "Wien", "priceMax": 1500, "maxItems": 500,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["price"], item["area_sqm"], item["postcode"], item["url"])
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('ninhothedev/willhaben-scraper').call({ vertical: 'auto', make: 'VW', maxItems: 200 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

### FAQ

**Is scraping willhaben.at legal?** The actor only collects publicly visible listing data, without logging in. You are responsible for using it lawfully. Private sellers' data is personal data under the GDPR, so only process it if you have a legitimate purpose.

**Which categories are supported?** Real estate (rent and buy apartments, houses, land, commercial, holiday homes, new-build projects), vehicles (cars, motorcycles and quads, commercial vehicles, caravans), the whole Marktplatz and jobs. For anything else, paste the willhaben URL.

**How many listings can I get?** As many as the search returns. willhaben shows the total for each search in the log. Use **Max listings** and **Max listings per search URL** to control cost.

**Do I need a proxy?** Usually not. willhaben works from Apify servers with plain HTTP. For very large runs you can enable Apify Proxy in *Advanced*.

**How do I get only new listings?** Sort by *Newest first* (the default) and set **Only listings published in the last X hours** (e.g. 24), then schedule the actor daily.

**Why are some fields empty?** Many fields only exist in some categories (rooms aren't listed for cars). Phone, website and full attributes need **Scrape full details**.

**Something broke or you need a field?** Open an issue on the actor's *Issues* tab. Issues are monitored and fixed quickly.

### Related actors by ninhothedev

- [Immowelt Scraper](https://apify.com/ninhothedev/immowelt-scraper): German real-estate listings
- [ImmoScout24 Scraper](https://apify.com/ninhothedev/immoscout24-scraper): German real-estate listings from ImmobilienScout24

# Actor input Schema

## `vertical` (type: `string`):

willhaben.at category to search. Ignored when you paste Search URLs below.

## `location` (type: `string`):

Bundesland (e.g. Wien, Steiermark, Tirol), Bezirk (e.g. Linz Land, Mödling), town (e.g. Graz) or postcode (e.g. 1100). Separate several with commas. Leave empty for all of Austria.

## `keyword` (type: `string`):

Free-text search, e.g. 'Balkon', 'iPhone 15', 'Golf GTI', 'Buchhaltung'.

## `maxItems` (type: `integer`):

Maximum number of listings to save in total (across all searches/URLs). You only pay for saved listings.

## `includeDetails` (type: `boolean`):

Opens every listing page to add the full description, all photos, every attribute (heating, energy rating, equipment, condition…), category path, seller/agency name, phone & website for commercial sellers, first-published and expiry dates. Slower (one extra request per listing).

## `searchUrls` (type: `array`):

Paste any willhaben.at search result URL (real estate, Marktplatz, Gebrauchtwagen, Jobs) with your filters already set on the website, or single listing URLs / ad IDs. When provided, the category and filter fields are ignored.

## `maxItemsPerSearch` (type: `integer`):

Optional cap per pasted URL, so one big search doesn't use up the whole Max listings budget. Leave empty for no per-URL limit.

## `sort` (type: `string`):

Order of results. 'Newest first' is best for monitoring new listings.

## `priceMin` (type: `integer`):

Minimum price or monthly rent in EUR.

## `priceMax` (type: `integer`):

Maximum price or monthly rent in EUR.

## `areaMin` (type: `integer`):

Real estate: minimum living area (plot area for land, usable area for commercial).

## `areaMax` (type: `integer`):

Real estate: maximum living area (plot area for land, usable area for commercial).

## `roomsMin` (type: `integer`):

Real estate: minimum number of rooms.

## `roomsMax` (type: `integer`):

Real estate: maximum number of rooms.

## `make` (type: `string`):

Vehicles: brand name as on willhaben, e.g. 'BMW', 'Volkswagen', 'KTM'.

## `yearMin` (type: `integer`):

Vehicles: minimum year of first registration.

## `yearMax` (type: `integer`):

Vehicles: maximum year of first registration.

## `mileageMax` (type: `integer`):

Vehicles: maximum mileage in km.

## `category` (type: `string`):

Marktplatz only: top-level category name as on willhaben, e.g. 'Computer / Software', 'Sport / Sportgeräte', 'Haus / Garten / Werkstatt'.

## `sellerType` (type: `string`):

Only private sellers, only commercial sellers (agencies, dealers, shops) or both.

## `maxAgeHours` (type: `integer`):

Great for scheduled monitoring: e.g. 24 = only listings published in the last 24 hours. Leave empty for no limit.

## `proxyConfiguration` (type: `object`):

Usually not needed – willhaben works without a proxy. Enable Apify Proxy only if you see blocking on very large runs.

## `maxConcurrency` (type: `integer`):

Maximum parallel requests (used for detail pages).

## Actor input object example

```json
{
  "vertical": "mietwohnungen",
  "location": "Wien",
  "maxItems": 20,
  "includeDetails": false,
  "sort": "newest",
  "sellerType": "all",
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "maxConcurrency": 8
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "vertical": "mietwohnungen",
    "location": "Wien",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("ninhothedev/willhaben-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "vertical": "mietwohnungen",
    "location": "Wien",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("ninhothedev/willhaben-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "vertical": "mietwohnungen",
  "location": "Wien",
  "maxItems": 20
}' |
apify call ninhothedev/willhaben-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ninhothedev/willhaben-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/9cGbX68cwMHoQR2ZB/builds/0uo6FbTcdXjx1GyEi/openapi.json
