# Etuovi Scraper - Finnish Real Estate Listings (`studio-amba/etuovi-scraper`) Actor

Scrape real estate listings from Etuovi.com -- Finland's #2 property portal. Search apartments and houses for sale by city, region, or nationwide. Get prices, sizes, rooms, locations, coordinates, images, and agency details. No login needed.

- **URL**: https://apify.com/studio-amba/etuovi-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 result scrapeds

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/platform/actors/running/actors-in-store#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

## Etuovi Scraper

Extract real estate listings from [Etuovi.com](https://www.etuovi.com) -- Finland's #2 property portal with tens of thousands of active listings -- into structured JSON with prices, sizes, room layouts, locations, coordinates, images, and agency details.

### What is Etuovi Scraper?

**Etuovi Scraper** extracts structured property data from Etuovi.com, helping you monitor the Finnish real estate market, compare prices across cities, and automate property research -- all without manual browsing or login.

- **Track property prices by city and district:** extract listings with prices, living area in m2, and room counts to build price maps across Helsinki, Tampere, Turku, Espoo, and every Finnish municipality
- **Monitor new listings automatically:** schedule daily runs and catch new apartments or houses the moment they appear on Etuovi
- **Build property datasets for analysis:** export thousands of listings with GPS coordinates, agency info, and building details for valuation models, academic research, or investment screening
- **Compare neighbourhoods within a city:** filter by district (e.g. Kallio, Munkkiniemi) or apply a price range to focus on a specific segment
- **Feed your CRM or dashboard:** export structured data to Google Sheets, Airtable, or any BI tool via Apify integrations

Etuovi.com has **no public API and no bulk export**. This scraper reads the JSON state Etuovi embeds in every search page to deliver clean, structured data at scale. No login, no cookies, no browser extensions needed.

### What data does Etuovi Scraper extract?

Each listing includes the following fields:

- **title** -- built from property subtype and address, e.g. "Apartment, Perustie 18, Munkkiniemi Helsinki"
- **propertyType** -- high-level category, always `"residential"` for now
- **propertySubtype** -- building type, e.g. "Apartment", "Detached house", "Row house", "Terraced house"
- **listingType** -- always `"sale"` (Etuovi.com lists for-sale property only; rentals live on the sister site vuokraovi.com)
- **price** -- asking price in EUR
- **currency** -- always `"EUR"`
- **pricePerSqm** -- calculated price divided by living area
- **area / totalArea** -- living area and total area in square meters
- **rooms** -- raw room structure, e.g. "2h, k, vh"
- **roomCount** -- normalized room count, e.g. "2", "3", "Studio"
- **address** -- street address
- **district** -- district or neighbourhood name
- **city** -- city or municipality name
- **location** -- full location string (address, district, city)
- **latitude / longitude** -- GPS coordinates for mapping
- **constructionYear** -- year the building was completed
- **floorLevel / buildingFloorCount** -- unit floor and total building floors
- **isNewBuilding** -- true if listed as a new-build property
- **publishedAt** -- ISO 8601 timestamp the listing was published or last updated
- **imageUrl / imageUrls** -- main property photo URL(s)
- **agencyName / agencyUrl** -- the real estate agency or seller office marketing the property
- **url** -- direct link to the listing on Etuovi.com
- **friendlyId** -- Etuovi's public listing identifier
- **scrapedAt** -- ISO 8601 timestamp when data was collected

### How to scrape Etuovi data

The input is simple: pick a **location**, optional **price range**, and hit run. You can configure the scraper through the Apify Console UI or programmatically via the API.

#### Input fields

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| **location** | String | -- | Finnish city or region, e.g. `"Helsinki"`, `"Tampere"`, `"Turku"`, `"Espoo"`. Leave empty for a nationwide search |
| **searchQuery** | String | -- | Free-text filter on title/district/city, e.g. `"Kallio"` |
| **priceFrom** | Integer | -- | Minimum price in EUR |
| **priceTo** | Integer | -- | Maximum price in EUR |
| **maxResults** | Integer | `50` | Maximum listings to return (0 = unlimited) |
| **proxyConfiguration** | Object | -- | Proxy settings (Finnish residential recommended) |

#### Tips for best results

- **Default input works out of the box** -- running with empty `{}` input returns a nationwide sweep of apartments and houses for sale
- **Use `location` for city-level filtering** -- set it to `"Helsinki"` or `"Tampere"` to narrow results geographically
- **Use `searchQuery` for district-level filtering** -- combine with `location` for precise results, e.g. `location: "Helsinki", searchQuery: "Kallio"`
- **Use price filters for budget ranges** -- set `priceFrom` and `priceTo` to focus on your target segment
- **Finnish residential proxy recommended** -- Etuovi works reliably from any residential IP. The default proxy config handles this automatically on Apify
- **Start small** -- test with `maxResults: 10` first, then scale up once you verify the output matches your needs

### Output

Results are stored in a **dataset** that you can download in JSON, CSV, Excel, XML, or HTML format directly from the Apify Console.

#### JSON example

```json
{
    "title": "Apartment, Perustie 18, Munkkiniemi Helsinki",
    "propertyType": "residential",
    "propertySubtype": "Apartment",
    "listingType": "sale",
    "price": 273000,
    "currency": "EUR",
    "pricePerSqm": 6067,
    "area": 45,
    "totalArea": 45,
    "rooms": "2h, k, vh",
    "roomCount": "2",
    "address": "Perustie 18",
    "district": "Munkkiniemi",
    "city": "Helsinki",
    "location": "Perustie 18 Munkkiniemi Helsinki",
    "latitude": 60.198,
    "longitude": 24.880809,
    "constructionYear": 1938,
    "floorLevel": 2,
    "buildingFloorCount": 6,
    "isNewBuilding": false,
    "publishedAt": "2026-08-04T16:52:33.494+03:00",
    "imageUrl": "https://d3ls91xgksobn.cloudfront.net/1200x900/etuovimedia/images/property/import/42/2667042/0e76b9541118d347871c0e0e51d244c4/e7611b59e237da999ad015151beba90f/ORIGINAL.jpeg",
    "imageUrls": [
        "https://d3ls91xgksobn.cloudfront.net/1200x900/etuovimedia/images/property/import/42/2667042/0e76b9541118d347871c0e0e51d244c4/e7611b59e237da999ad015151beba90f/ORIGINAL.jpeg"
    ],
    "agencyName": "Kiinteistomaailma Espoo Tapiola | Amuletti Asunnot Oy",
    "agencyUrl": "http://www.kiinteistomaailma.fi/",
    "url": "https://www.etuovi.com/kohde/50544969",
    "friendlyId": "50544969",
    "scrapedAt": "2026-08-04T14:22:47.062Z"
}
```

### How much does it cost to scrape Etuovi?

Etuovi Scraper reads directly from the JSON state Etuovi embeds in its own search pages -- no browser rendering needed. This makes it fast and very affordable.

| Scenario | Est. cost | Time |
|----------|-----------|------|
| 50 listings | ~$0.05 | ~15 sec |
| 500 listings | ~$0.25 | ~1.5 min |
| 5,000 listings | ~$1.50 | ~8 min |

### Can I integrate Etuovi Scraper with other apps?

Yes. Etuovi Scraper connects with any tool through [Apify integrations](https://apify.com/integrations):

- **Google Sheets** -- automatically export property data to a spreadsheet
- **Slack / Email** -- get notified when new listings match your criteria
- **Zapier / Make** -- trigger workflows when data is ready
- **Airtable** -- build a searchable property database
- **REST API** -- call the scraper programmatically from any language
- **Webhooks** -- get notified when a run finishes

### Can I use Etuovi Scraper as an API?

Yes. Use the [Apify API](https://docs.apify.com/api/v2) to run Etuovi Scraper programmatically.

**Python:**

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("studio-amba/etuovi-scraper").call(run_input={
    "location": "Helsinki",
    "maxResults": 200,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['title']} -- EUR {item['price']:,} -- {item['city']}")
```

**JavaScript:**

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

const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('studio-amba/etuovi-scraper').call({
    location: 'Helsinki',
    maxResults: 200,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Check the [API tab](https://apify.com/studio-amba/etuovi-scraper/api) for full documentation.

### FAQ

#### What is Etuovi.com?

Etuovi.com is Finland's #2 real estate portal, operated by Alma Media. It lists tens of thousands of active properties -- apartments, detached houses, row houses, and terraced houses -- for sale across every Finnish municipality, from Helsinki and the greater capital region to smaller towns nationwide.

#### How does Etuovi Scraper work?

Every Etuovi search page (e.g. `/myytavat-asunnot/helsinki`) server-renders a `window.__INITIAL_STATE__` JSON blob containing the current page of listings. The scraper reads that blob directly with plain HTTP requests -- no browser needed -- and pages through results using Etuovi's own `?sivu=` (page) parameter, 30 listings per page.

#### Does Etuovi Scraper include rentals?

No. Etuovi.com only lists property **for sale**. Finnish rental listings live on the sister site vuokraovi.com, which is a separate portal outside this scraper's scope.

#### Can I filter by city or district?

Yes. Set `location` to any Finnish city or region name, e.g. `"Helsinki"`, `"Tampere"`, `"Turku"`, `"Oulu"`, `"Espoo"`. For neighbourhood-level filtering within a city, combine `location` with `searchQuery`, e.g. `location: "Helsinki", searchQuery: "Kallio"`.

#### Can I filter by price range?

Yes. Use `priceFrom` and `priceTo` to set a EUR price range. For example, apartments between 150,000 EUR and 400,000 EUR: `priceFrom: 150000, priceTo: 400000`.

#### Is it legal to scrape Etuovi?

This scraper extracts publicly available listing data that Etuovi.com displays to all visitors. The data is factual (prices, addresses, property specifications) and does not contain private personal information. As with any scraping tool, use the data responsibly and in compliance with applicable laws.

### Limitations

- **Finland only, for-sale listings only.** Etuovi.com covers Finnish real estate for sale; rentals are on vuokraovi.com and out of scope for this actor.
- **List-page data only.** Fields come from Etuovi's search-result payload, not individual listing pages -- long-form descriptions are not included, but every structured field (price, size, rooms, location, coordinates, images, agency) is.
- **Some fields may be null.** Not all sellers provide complete information -- `constructionYear`, `floorLevel`, or `agencyUrl` may be missing on some listings.
- **Finnish city/region names.** The `location` filter matches Etuovi's own URL slugs; both accented ("Jyväskylä") and unaccented ("Jyvaskyla") spellings work.

### Other Nordic and European real estate scrapers

Combine Etuovi Scraper with these actors for comprehensive European property market coverage:

- [Oikotie Scraper](https://apify.com/studio-amba/oikotie-scraper) -- Finland's #1 real estate portal
- [Hemnet Scraper](https://apify.com/studio-amba/hemnet-scraper) -- Swedish real estate listings
- [Immoweb Scraper](https://apify.com/studio-amba/immoweb-scraper) -- Belgian real estate listings
- [ImmoScout24 Scraper](https://apify.com/studio-amba/immoscout24-scraper) -- German real estate
- [Idealista Scraper](https://apify.com/studio-amba/idealista-scraper) -- Spanish real estate
- [Sreality Scraper](https://apify.com/studio-amba/sreality-scraper) -- Czech real estate listings

### Your feedback

Found a bug or have a feature request? Please open an issue on the [Issues tab](https://apify.com/studio-amba/etuovi-scraper/issues). We actively maintain this scraper and respond to all reports.

# Actor input Schema

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

Finnish city or region name to search, e.g. 'Helsinki', 'Tampere', 'Turku', 'Espoo'. Leave empty to search nationwide.

## `searchQuery` (type: `string`):

Optional free-text filter applied to the listing title, district, and city, e.g. 'Kallio' or 'kerrostalo'.

## `priceFrom` (type: `integer`):

Minimum asking price in euros, e.g. 100000.

## `priceTo` (type: `integer`):

Maximum asking price in euros, e.g. 500000.

## `maxResults` (type: `integer`):

Maximum number of listings to return. Set to 0 for unlimited.

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

Proxy settings. Finnish residential proxy recommended for best results.

## Actor input object example

```json
{
  "location": "Helsinki",
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FI"
  }
}
```

# 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": "Helsinki",
    "maxResults": 50,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "FI"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/etuovi-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": "Helsinki",
    "maxResults": 50,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "FI",
    },
}

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

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": "Helsinki",
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FI"
  }
}' |
apify call studio-amba/etuovi-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=studio-amba/etuovi-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dlAYVnGXLFoiSCdWh/builds/3Vv4CbVcsvVniXtlk/openapi.json
