# Xe.gr Scraper - Greek Commercial Property & Land (`studio-amba/xe-gr-commercial-scraper`) Actor

Scrape commercial property and land listings from xe.gr, Greece's largest classifieds portal: offices, stores, industrial and craft spaces, plots and parcels for rent or sale. Prices in EUR, price per m2, surfaces, coordinates and agency names.

- **URL**: https://apify.com/studio-amba/xe-gr-commercial-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

## Xe.gr Commercial Property Scraper

Scrape commercial property and land listings from [xe.gr](https://www.xe.gr) (Χρυσή Ευκαιρία), Greece's largest classifieds portal. The property section carries roughly 60,000 commercial-space ads (επαγγελματικοί χώροι: offices, stores, commercial buildings, industrial and craft spaces, storage units) and over 90,000 land ads (γη και οικόπεδα: plots, agricultural parcels, even whole islands), for rent and for sale, across the whole country.

Each result comes from the portal's own data feed, not parsed page text. You get the asking price in EUR, price per m2, surface, coordinates, floor levels, the listing agency's name, photos and a direct link to the listing.

### Why use it

- **Market research**. Track asking prices and rents per area or segment across Greece, from Athens office space to island plots.
- **Site selection**. Compare store and office rents per m2 between neighbourhoods before signing a lease.
- **Land sourcing**. Filter plots (οικόπεδα) and agricultural parcels (αγροτεμάχια) by area. Land listings include planning attributes like "Εντός σχεδίου" (within the city plan) and the building coefficient (Σ.Δ) where published.
- **Investment screening**. Sale listings carry total price, price per m2 and surface, so screening by yield inputs is straightforward.
- **Monitoring**. Run it on a schedule and diff against yesterday's dataset to catch new listings the day they appear.

### How to scrape Xe.gr data

1. Set **Location** to any Greek city, area or region. Greek and Latin spellings both work: `Αθήνα` or `Athina`, `Θεσσαλονίκη` or `Thessaloniki`. The actor resolves your text through xe.gr's own location autocomplete, so anything the site's search box accepts works here too. Leave it empty to search all of Greece.
2. Pick a **Listing Type**: rent (ενοικίαση), sale (πώληση) or both.
3. Pick a **Property Segment**: offices, stores, commercial buildings, industrial spaces, craft spaces, storage units, or on the land side plots, agricultural parcels and islands.
4. Set **Max Results** and run. Results land in the dataset as one flat JSON object per listing.

Example: office space for rent in Athens:

```json
{
    "searchQuery": "Αθήνα",
    "listingType": "rent",
    "segment": "office",
    "maxResults": 200
}
```

Example: plots for sale in Thessaloniki:

```json
{
    "searchQuery": "Θεσσαλονίκη",
    "listingType": "sale",
    "segment": "plot",
    "maxResults": 100
}
```

Example: every commercial listing in Patras, rent and sale:

```json
{
    "searchQuery": "Patra",
    "segment": "all_commercial",
    "maxResults": 500
}
```

### Input options

| Field | Type | Description |
|---|---|---|
| `searchQuery` | string | Location in Greece, Greek or Latin spelling (`Αθήνα`, `Athina`, `Θεσσαλονίκη`, `Thessaloniki`). Empty searches the whole country. |
| `listingType` | string | `all` (default), `rent` or `sale`. |
| `segment` | string | `all_commercial` (default), `office`, `store`, `commercial_building`, `industrial_space`, `craft_space`, `storage_unit`, `all_land`, `plot`, `parcel`, `island`. |
| `sorting` | string | Empty for the site default, `price_asc` or `price_desc`. |
| `maxResults` | integer | Cap on returned listings. Default 100, maximum 10,030 per query (the portal caps pagination at 295 pages). Narrow by location or segment to reach deeper into the catalog. |
| `proxyConfiguration` | object | Greek residential proxy, preconfigured. Required, see Limitations. |

### Output fields

| Field | Example | Notes |
|---|---|---|
| `title` | `"Γραφείο 120 τ.μ."` | Property type + surface, as published |
| `listingType` | `"rent"` | `rent` or `sale` |
| `segment` | `"Office"` | English label derived from the Greek type |
| `propertyTypeGr` | `"Γραφείο"` | Greek property type as published |
| `category` | `"commercial"` | `commercial` or `land` |
| `price` | `980` | EUR. Sale: total. Rent: per month. Null when price on request |
| `currency` | `"EUR"` | Always EUR when a price exists |
| `priceUnit` | `"EUR/month"` | `EUR/month` for rentals, `EUR total` for sales |
| `priceRaw` | `"980 €"` | Price text exactly as published |
| `pricePerM2` | `8.52` | EUR per m2, computed by xe.gr |
| `surface` | `115` | m2 (floor area, or plot area for land) |
| `address` | `"Ταύρος Αττικής (Κέντρο)"` | Area and neighbourhood |
| `latitude`, `longitude` | `37.9724`, `23.6928` | Listing coordinates |
| `floorLevels` | `["1ος"]` | Commercial spaces only |
| `constructionYear` | `1998` | Where published |
| `details` | `["Εντός σχεδίου", "Σ.Δ: 0.8"]` | Planning attributes, mostly on land |
| `agencyName` | `"Aspis Real Estate"` | Null for private listings |
| `isAgency` | `true` | Professional agency account or not |
| `sponsored` | `false` | Sponsored tile flag |
| `publishedAgo` | `"πριν από 2 ημέρες"` | Listing age as shown on the site |
| `imageUrl`, `imageUrls` | `https://blob.cdn.xe.gr/...` | Up to 10 photo URLs |
| `url` | `https://www.xe.gr/property/d/...` | Listing detail page |
| `id` | `"b54e4604-..."` | xe.gr listing UUID |
| `source` | `"xe.gr"` | |
| `scrapedAt` | `"2026-08-18T11:20:00.000Z"` | |

### Example output

```json
{
    "title": "Βιοτεχνικός χώρος 115 τ.μ.",
    "listingType": "rent",
    "segment": "Craft space",
    "propertyTypeGr": "Βιοτεχνικός χώρος",
    "category": "commercial",
    "price": 980,
    "currency": "EUR",
    "priceUnit": "EUR/month",
    "priceRaw": "980 €",
    "pricePerM2": 8.52,
    "surface": 115,
    "surfaceRaw": "115 τ.μ.",
    "address": "Ταύρος Αττικής (Κέντρο)",
    "latitude": 37.9724122,
    "longitude": 23.6927849,
    "floorLevels": ["1ος"],
    "constructionYear": null,
    "details": [],
    "agencyName": null,
    "isAgency": false,
    "sponsored": false,
    "publishedAgo": "πριν από 2 ημέρες",
    "imageUrl": "https://blob.cdn.xe.gr/live/2026/08/16/9c2bd914-ff96-469b-9c95-06b94ad506c5/9c2bd914-ff96-469b-9c95-06b94ad506c5-source.jpg?width=640&height=480&format=jpg",
    "url": "https://www.xe.gr/property/d/enoikiaseis-epaggelmatikon-xoron/b54e4604-71a1-4441-b7d1-0d356857189a/tayros-attikhs-kentro-980-115",
    "id": "b54e4604-71a1-4441-b7d1-0d356857189a",
    "source": "xe.gr",
    "scrapedAt": "2026-08-18T11:20:00.000Z"
}
```

### Cost estimate

Pricing is pay per event: a small flat fee per run start plus a fee per result, about $0.002 per listing. $1 buys roughly 500 listings. Compute is minimal (the actor reads the portal's JSON feed at 34 listings per request), so the per-result fee is effectively the whole cost.

A run's usage cost only settles after the run reports SUCCEEDED. A cost read mid-run shows a fraction of the final number, so don't estimate spend from a run that is still going.

### Limitations and known issues

- **Prices can be missing.** Price on request is normal in commercial real estate. The `price` field is null in that case and `priceRaw` carries whatever the site showed. The actor never invents a number.
- **Rent is quoted per month.** Greek commercial rents on xe.gr are monthly (€/μήνα). The `priceUnit` field says which quote you're looking at.
- **About 10,000 results per query.** The portal caps pagination at 295 pages of 34 listings. To pull more than that, split the work across several runs by location or segment.
- **Halls (αίθουσες) have no dedicated segment filter** on the portal's API. They are included in `all_commercial` results.
- **Greek residential proxy is required.** The site sits behind AWS WAF and CloudFront, which serve a captcha to non-Greek and datacenter IPs. The default proxy configuration handles this; changing it will most likely break the actor.
- **Listing-level data only.** The actor scrapes the search feed, which is where price, surface, location, coordinates and agency live. It does not open every detail page, which keeps runs fast and cheap.

# Actor input Schema

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

City, area or region in Greece (e.g. 'Αθήνα', 'Θεσσαλονίκη', 'Πάτρα'). Greek and Latin spellings both work ('Αθήνα' or 'Athina') — the actor resolves it through xe.gr's own location autocomplete. Leave empty to search all of Greece.

## `listingType` (type: `string`):

Rent (ενοικίαση), sale (πώληση), or both.

## `segment` (type: `string`):

Commercial segment or land type as xe.gr defines them. 'All commercial spaces' covers offices, stores, buildings, industrial/craft spaces, storage units and halls; 'All land' covers plots, parcels and islands.

## `sorting` (type: `string`):

How xe.gr orders the results. Empty uses the site default (recommended listings first).

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

Maximum number of listings to return. One search query can return at most about 10,000 listings (the portal caps pagination at 295 pages of 34) — narrow by location or segment to reach deeper into the 60k+ commercial and 90k+ land listings.

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

Proxy settings. xe.gr sits behind AWS WAF + CloudFront which serves a captcha to non-Greek and datacenter IPs (verified in recon, see docs/site-recon/xe-gr.md) — Greek residential proxy is required.

## Actor input object example

```json
{
  "searchQuery": "Αθήνα",
  "listingType": "all",
  "segment": "all_commercial",
  "sorting": "",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GR"
  }
}
```

# 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 = {
    "searchQuery": "Αθήνα",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "GR"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/xe-gr-commercial-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 = {
    "searchQuery": "Αθήνα",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "GR",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/xe-gr-commercial-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 '{
  "searchQuery": "Αθήνα",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "GR"
  }
}' |
apify call studio-amba/xe-gr-commercial-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/xe-gr-commercial-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/S2YNLDIjTMMkbQg2B/builds/1HvcF168yVllhesV9/openapi.json
