# Comparis.ch Real Estate Scraper (`unfenced-group/comparis-scraper`) Actor

Scrape Swiss real estate from comparis.ch — apartments, houses, rooms, land, for rent or buy. Structured data: gross & net rent, extra costs, rooms, m², floor, year built, coordinates, amenities and photos. Filter by city, price, size and type. No API key required.

- **URL**: https://apify.com/unfenced-group/comparis-scraper.md
- **Developed by:** [Unfenced Group](https://apify.com/unfenced-group) (community)
- **Categories:** Real estate, Automation, Developer tools
- **Stats:** 9 total users, 2 monthly users, 76.7% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.79 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Comparis.ch Real Estate Scraper

![Comparis.ch Real Estate Scraper](https://api.apify.com/v2/key-value-stores/ClElVyZWvQgPQIuDL/records/comparis-scraper)

Extract Swiss property listings from comparis.ch at scale — apartments, houses, rooms, land and holiday homes, for rent or for sale. Full descriptions, prices, floor area, coordinates, amenities and photos. No API key required.

***

### Why this scraper?

#### 🎯 Built for Switzerland

A dedicated Swiss scraper, not a global tool with a country dropdown. Price handling, room counts and location matching follow how comparis.ch actually publishes listings, in CHF.

#### 🏘️ Every property type

Apartments, houses, flatshare rooms, furnished apartments, land plots and holiday properties — rent or buy, in one input.

#### 📄 Complete listing data

Title, full description, price and price type, rooms, living area, floor and year built, plus every photo published on the listing.

#### 📍 Precise location

Street, street number, postal code and city, with latitude and longitude taken from the listing's own map position.

#### 🔎 Server-side filters

City or canton, price range, room range and listing age are applied at the source, so you retrieve only what you asked for.

#### 🔗 Direct URL mode

Paste comparis.ch search result URLs and the scraper follows them exactly, filters and all.

***

### Input parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | (empty) | Comparis.ch search result page URLs to scrape directly. When provided, all filters below are ignored. |
| `location` | string | `"zuerich"` | Swiss city or canton slug, for example `zuerich`, `bern`, `basel`, `luzern`, `lausanne`, `geneve`, `zug`, `winterthur`. |
| `propertyType` | string | `"wohnung"` | `wohnung`, `haus`, `wg-zimmer`, `moebilierte-wohnung`, `grundstueck` or `ferienimmobilie`. |
| `dealType` | string | `"mieten"` | `mieten` for rentals, `kaufen` for properties for sale. |
| `sortBy` | string | `"newest"` | `newest`, `relevance`, `price_asc`, `area` or `city`. |
| `minRooms` | number | (empty) | Minimum number of rooms, for example 2, 2.5, 3. |
| `maxRooms` | number | (empty) | Maximum number of rooms. |
| `minPriceChf` | integer | (empty) | Minimum price in CHF — per month for rentals, total for sales. |
| `maxPriceChf` | integer | (empty) | Maximum price in CHF. |
| `daysOld` | integer | (empty) | Only return listings published within the last N days. |
| `maxItems` | integer | `20` | Maximum number of listings to return. |
| `fetchDetails` | boolean | `true` | Fetch each listing's detail page for the full description, all photos, coordinates and amenities. |

***

### Output schema

Every field below is present on every record. Fields comparis.ch does not publish for a given listing are returned as `null` rather than omitted.

#### Always present

| Field | Type | Description |
|---|---|---|
| `adId` | number | Comparis listing ID, stable for the life of the advert. |
| `url` | string | Direct link to the listing on comparis.ch. |
| `title` | string | Listing headline as published by the advertiser. |
| `propertyType` | string | Property category in German, for example `Wohnung`, `Villa`, `Reiheneinfamilienhaus`. |
| `dealType` | string | `rent` or `buy`. |
| `street` | string | Street name and number where published, otherwise empty. |
| `postalCode` | string | Four-digit Swiss postal code. |
| `city` | string | Municipality name. |
| `rooms` | number | Number of rooms, half rooms included (null if not published). |
| `areaM2` | number | Living area in square metres (null if not published). |
| `priceText` | string | Price as displayed, for example `CHF 1'425`. |
| `priceValue` | number | Price as a plain number for sorting and filtering. |
| `currency` | string | Always `CHF`. |
| `priceType` | string | What the price covers, for example `Mietpreis pro Monat` or `Kaufpreis`. |
| `partnerName` | string | Advertising agency or portal that supplied the listing. |
| `imageUrl` | string | Primary listing photo. |
| `imageUrls` | array | All listing photos available at this stage. |
| `listedDate` | string | When the listing was published, ISO 8601. |
| `contentHash` | string | Hash of ID, price, rooms and area — changes when the advert changes. |
| `source` | string | Always `comparis.ch`. |
| `scrapedAt` | string | Timestamp of retrieval, ISO 8601. |

#### With `fetchDetails: true`

| Field | Type | Description |
|---|---|---|
| `description` | string | Full advertiser description as plain text. |
| `features` | array | Amenities and property attributes, for example `Balkon/Terrasse/Sitzplatz`, `Lift`, `Kinderfreundlich` (null when the advertiser lists none). |
| `floor` | string | Floor for apartments, number of storeys for houses (null if not published). |
| `constructionYear` | number | Year built (null if not published). |
| `latitude` | number | Listing map latitude. |
| `longitude` | number | Listing map longitude. |

Detail fetching also upgrades `street`, `postalCode`, `city`, `rooms`, `areaM2`, `priceText`, `priceValue`, `imageUrl` and `imageUrls` to the fuller values on the listing page.

#### Example record

```json
{
  "adId": 37996139,
  "url": "https://www.comparis.ch/immobilien/marktplatz/details/show/37996139",
  "title": "Schöne 1-Zimmerwohnung in Zürich (befristet bis 03.2027)",
  "propertyType": "Wohnung",
  "dealType": "rent",
  "street": "Langgrütstrasse 25",
  "postalCode": "8047",
  "city": "Zürich",
  "rooms": 1,
  "areaM2": 32,
  "floor": "3",
  "priceText": "CHF 1'425",
  "priceValue": 1425,
  "currency": "CHF",
  "priceType": "Mietpreis pro Monat",
  "partnerName": "Immobilien Zürich AG",
  "imageUrl": "https://mapl-assets.b-cdn.net/immobilien/images/datacollect/e9906f3d-411d-64a4-0475-96727e4c11ce.avif",
  "imageUrls": [
    "https://mapl-assets.b-cdn.net/immobilien/images/datacollect/e9906f3d-411d-64a4-0475-96727e4c11ce.avif",
    "https://mapl-assets.b-cdn.net/immobilien/images/datacollect/7c21a0ab-9d34-41ee-9f10-2b6c1a0d5e83.avif"
  ],
  "listedDate": "2026-09-10T05:59:21",
  "latitude": 47.37279578179405,
  "longitude": 8.501640337724266,
  "constructionYear": null,
  "description": "Helle 1-Zimmerwohnung an ruhiger Lage in Zürich Albisrieden. Balkon nach Süden, Tram- und Busverbindung in Gehdistanz. Befristet bis März 2027.",
  "features": ["Balkon/Terrasse/Sitzplatz", "Haustiere erlaubt"],
  "contentHash": "a41f9c72b0e5d183",
  "source": "comparis.ch",
  "scrapedAt": "2026-09-10T05:43:15.177Z"
}
```

***

### Examples

**Rental apartments in Zürich, newest first:**

```json
{
  "location": "zuerich",
  "propertyType": "wohnung",
  "dealType": "mieten",
  "sortBy": "newest",
  "maxItems": 100
}
```

**Family houses for sale in Bern up to CHF 1.5m:**

```json
{
  "location": "bern",
  "propertyType": "haus",
  "dealType": "kaufen",
  "minRooms": 4,
  "maxPriceChf": 1500000,
  "maxItems": 200
}
```

**Scrape a comparis.ch search URL directly:**

```json
{
  "startUrls": [
    { "url": "https://www.comparis.ch/immobilien/result/list?requestobject=%7B%22DealType%22%3A10%2C%22RootPropertyTypes%22%3A%5B1%5D%2C%22LocationSearchString%22%3A%22basel%22%2C%22Sort%22%3A3%7D" }
  ],
  "maxItems": 100
}
```

**Daily feed of new listings only:**

```json
{
  "location": "geneve",
  "propertyType": "wohnung",
  "dealType": "mieten",
  "daysOld": 1,
  "sortBy": "newest",
  "maxItems": 500
}
```

***

### 💰 Pricing

**$0.99 per 1,000 results** — you only pay for successfully retrieved listings. Failed retries are never charged.

| Results | Cost |
|---|---|
| 100 | ~$0.10 |
| 1,000 | ~$0.99 |
| 10,000 | ~$9.90 |
| 100,000 | ~$99.00 |

> Flat-rate alternatives typically charge $29–$49/month regardless of usage.

Subscription tiers lower the rate further, down to $0.59 per 1,000 at the highest tier. Use the **Max Items** cap in the input to control your spend exactly.

***

### Performance

| Run size | Typical time |
|---|---|
| 20 results with details | under 1 minute |
| 100 results with details | 2–3 minutes |
| 1,000 results with details | 20–30 minutes |

Turning `fetchDetails` off returns roughly ten times as many listings in the same time, with the list-level fields only.

***

### Known limitations

- Living area, year built and floor are frequently not published by the advertiser, especially on rental listings. These fields return `null` rather than a guess.
- A single search returns at most 1,000 listings. Split larger jobs by city, price band or property type.
- Very large runs can stop short of the requested `maxItems` when the source throttles sustained traffic. The run still finishes successfully with the listings it collected; re-running picks up the rest.
- Descriptions are in the language the advertiser used — German, French or Italian depending on the region.
- Advertiser contact names, phone numbers and email addresses are never returned.

***

### Technical details

- **Source:** comparis.ch — Swiss property marketplace, rentals and sales
- **Coverage:** nationwide, filterable by city or canton, price, rooms and listing age
- **Memory:** 256 MB
- **Retry:** automatic retry on rejected and failed requests, with a fresh identity per attempt and an automatic fallback route when the source throttles

***

### Rate this actor

If this scraper does its job, a short review on the **Reviews** tab helps other users find it. Something not working? Open an issue on the **Issues** tab instead — issues get fixed.

***

### Need a custom scraper?

**[Unfenced Group](https://www.unfencedgroup.nl)** builds Apify actors for any website — for free.

If the site you need isn't in our portfolio yet, just ask. We scope, build, and publish it at no cost to you. You only pay for results — we absorb the compute and proxy costs ourselves. Same pay-per-result pricing, same quality, same standards as every actor in this portfolio.

**Get in touch:** [www.unfencedgroup.nl](https://www.unfencedgroup.nl)

# Actor input Schema

## `startUrls` (type: `array`):

Comparis.ch search result page URLs to scrape directly. When provided, all filter inputs below are ignored.

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

Swiss city or canton slug. Examples: zuerich, bern, basel, luzern, lausanne, geneve, zug, winterthur. Leave empty when using startUrls.

## `propertyType` (type: `string`):

Type of property to search for.

## `dealType` (type: `string`):

Whether to search for rentals or properties for sale.

## `sortBy` (type: `string`):

Sort order for results.

## `minRooms` (type: `number`):

Minimum number of rooms (e.g. 2, 2.5, 3).

## `maxRooms` (type: `number`):

Maximum number of rooms (e.g. 4, 4.5).

## `minPriceChf` (type: `integer`):

Minimum price in CHF per month (rent) or total (buy).

## `maxPriceChf` (type: `integer`):

Maximum price in CHF per month (rent) or total (buy).

## `daysOld` (type: `integer`):

Only return listings published within the last N days.

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

Maximum number of listings to return.

## `fetchDetails` (type: `boolean`):

Fetch each listing detail page for full description, all images, coordinates and features. Adds one request per listing.

## Actor input object example

```json
{
  "location": "zuerich",
  "propertyType": "wohnung",
  "dealType": "mieten",
  "sortBy": "newest",
  "maxItems": 20,
  "fetchDetails": true
}
```

# Actor output Schema

## `results` (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 = {
    "location": "zuerich",
    "propertyType": "wohnung",
    "dealType": "mieten",
    "sortBy": "newest",
    "maxItems": 20,
    "fetchDetails": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("unfenced-group/comparis-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 = {
    "location": "zuerich",
    "propertyType": "wohnung",
    "dealType": "mieten",
    "sortBy": "newest",
    "maxItems": 20,
    "fetchDetails": True,
}

# Run the Actor and wait for it to finish
run = client.actor("unfenced-group/comparis-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 '{
  "location": "zuerich",
  "propertyType": "wohnung",
  "dealType": "mieten",
  "sortBy": "newest",
  "maxItems": 20,
  "fetchDetails": true
}' |
apify call unfenced-group/comparis-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,unfenced-group/comparis-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/XnoIMJWZHXEzKb21M/builds/NphdP6vYawukP6IhO/openapi.json
