# Commerciali.it Scraper — Italian Commercial Property (`studio-amba/commerciali-it-scraper`) Actor

Get Italian commercial property listings from Commerciali.it, Immobiliare.it's commercial portal: uffici, negozi, capannoni, magazzini and more, for sale or rent. Prices, surfaces, locations, images and agency IDs as structured JSON. No login required.

- **URL**: https://apify.com/studio-amba/commerciali-it-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

## Commerciali.it Scraper: Italian Commercial Property Listings

Get commercial property listings from [Commerciali.it](https://www.commerciali.it), Immobiliare.it's dedicated commercial portal and one of the largest sources of Italian commercial real estate. The portal carries over 100,000 listings across every Italian comune and province: uffici (offices), negozi (shops), capannoni (industrial sheds), magazzini (warehouses), laboratori (workshops), alberghi (hotels), palazzine commerciali, aziende agricole and attività commerciali.

Search by comune or province, filter by segment, contract type and price, and get structured JSON with prices, surfaces, room counts, locations, photos and agency IDs. No login or cookies required.

### Why use it

- **Market research**: track asking prices and rents per segment, comune or province.
- **Deal sourcing**: investors and occupiers monitoring new commercial stock in a target area.
- **Portfolio benchmarking**: compare your own asking prices against the local market.
- **Lead generation**: every listing carries the advertising agency's internal ID, so you can group stock by agency.
- **Site selection**: retail and logistics teams comparing availability and price levels across Italian cities.

### A note on prices

Commerciali.it never labels the price period. Rental listings mix conventions: large offices are usually quoted as annual canone (a 620 m2 Milan office at € 90.000 per year), while small units are often quoted monthly. The site's own price filter works on the raw number either way. This actor never converts or guesses: you get the numeric `price`, the displayed `priceText`, and `priceUnit` stays null. When the period matters for your analysis, the listing page linked in `url` usually states it in the description.

### Input options

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `searchQuery` | string | (Milano) | Italian comune (`Milano`, `Torino`, `Sesto San Giovanni`) or a province as `provincia-XX` (`provincia-mi`, `provincia-to`). The site requires a location; when left empty the actor searches Milano. |
| `listingType` | string | `rent` | `rent` (affitto) or `sale` (vendita). |
| `segment` | string | `all` | `all`, `uffici`, `negozi`, `capannoni`, `magazzini`, `laboratori`, `alberghi`, `palazzine-commerciali`, `aziende-agricole`, or `attivita-commerciali`. |
| `minPrice` | integer | none | Only listings priced at or above this amount (EUR, raw quoted number). |
| `maxPrice` | integer | none | Only listings priced at or below this amount (EUR, raw quoted number). |
| `maxResults` | integer | `100` | Hard cap on returned listings. A province search can return several thousand. |
| `proxyConfiguration` | object | Italian residential | Commerciali.it sits behind Cloudflare. Italian residential proxy is the reliable default. |

#### Example input

```json
{
    "searchQuery": "milano",
    "segment": "uffici",
    "listingType": "rent",
    "maxResults": 100
}
```

Or the whole province of Turin, industrial sheds for sale:

```json
{
    "searchQuery": "provincia-to",
    "segment": "capannoni",
    "listingType": "sale",
    "maxResults": 500
}
```

### Output fields

| Field | Type | Example | Description |
|-------|------|---------|-------------|
| `id` | string | `"30630466"` | Commerciali.it listing ID |
| `title` | string | `"Via Privata Branda Castiglioni, Milano"` | Street address plus comune |
| `address` | string | null | `"Via Privata Branda Castiglioni"` | Street part of the title |
| `city` | string | null | `"Milano"` | Comune |
| `segment` | string | null | `"Ufficio"` | Typology label as shown on the site |
| `listingType` | string | `"rent"` | `sale` or `rent`, from the listing URL |
| `price` | number | null | `90000` | Asking price in EUR as quoted; null when not published |
| `currency` | string | `"EUR"` | Always EUR |
| `priceText` | string | null | `"€ 90.000"` | Price as displayed |
| `priceUnit` | string | null | `null` | Always null; the site does not label the price period |
| `surface` | number | null | `620` | Floor area in m2 |
| `surfaceUnit` | string | null | `"m2"` | |
| `rooms` | number | null | `3` | Locali, when listed |
| `bathrooms` | number | null | `5` | Bagni, when listed (`5+` is reported as 5) |
| `badge` | string | null | `"Top"` | Paid-placement flag, when present |
| `agencyId` | string | null | `"107928"` | Advertising agency's internal ID |
| `imageUrl` | string | null | | Primary listing photo |
| `imageUrls` | array | | All photos from the card carousel |
| `url` | string | | Canonical listing page URL |
| `source` | string | `"commerciali.it"` | |
| `scrapedAt` | string | | ISO 8601 timestamp |

#### Example output

```json
{
    "id": "30630466",
    "title": "Via Privata Branda Castiglioni, Milano",
    "address": "Via Privata Branda Castiglioni",
    "city": "Milano",
    "segment": "Ufficio",
    "listingType": "rent",
    "price": 90000,
    "currency": "EUR",
    "priceText": "€ 90.000",
    "priceUnit": null,
    "surface": 620,
    "surfaceUnit": "m2",
    "rooms": null,
    "bathrooms": 5,
    "badge": "Top",
    "agencyId": "107928",
    "imageUrl": "https://images.wk-cdn.it/f8d9dd716eba09ac361712e4243840c1f5fef0aa2e107777460d08e3fbfd5904/webp/1280x960.webp",
    "imageUrls": ["https://images.wk-cdn.it/f8d9dd716eba09ac361712e4243840c1f5fef0aa2e107777460d08e3fbfd5904/webp/640x480.webp"],
    "url": "https://www.commerciali.it/ufficio-affitto-milano-zona-varesina-cagnola-villapizzone-ghisolfa-30630466",
    "source": "commerciali.it",
    "scrapedAt": "2026-08-18T09:00:00.000Z"
}
```

### How to scrape Commerciali.it data

1. Set `searchQuery` to an Italian comune (`milano`, `roma`, `bologna`) or a province (`provincia-mi`). Multi-word comuni work as typed: `Sesto San Giovanni`.
2. Pick a `segment` (for example `uffici` for offices or `capannoni` for industrial sheds) or leave `all` for every commercial typology.
3. Pick `listingType`: `rent` for affitto, `sale` for vendita.
4. Optionally set `minPrice` and `maxPrice` in EUR.
5. Set `maxResults` and run. The actor paginates through the result pages (20 listings per page) and stops at your cap or at the end of the results.
6. Export from the dataset as JSON, CSV or Excel, or read it via the Apify API.

Typical searches: `uffici` + `milano` (about 1,700 rentals), `capannoni` + `torino`, `negozi` + `roma`, or a whole province like `provincia-mi` (3,000+ office rentals).

### Cost of usage

The actor charges per result (see the pricing section on this page). One page fetch returns 20 listings, so runs are cheap on compute: a 100-result run makes about 6 lightweight HTTP requests through the proxy. Residential proxy traffic is the main platform cost driver; a few MB per hundred listings is typical.

A run's usage cost only settles after the run reaches the SUCCEEDED state. If a run fails, you are not charged for results.

### Limitations

- The card data does not include the full description or exact coordinates; those live on the individual listing page linked in `url`.
- `priceUnit` is always null because the site does not publish the price period (see the price note above).
- The location must be an Italian comune or province the portal knows; an unknown location falls back to Milano with a warning in the log.
- The portal has no separate land (terreni) segment; `aziende-agricole` is the closest typology.

### Related actors

- [Immobiliare.it Scraper](https://apify.com/studio-amba/immobiliare-scraper) for Italian residential listings on the parent portal.
- Commercial property scrapers for other European markets: NovaLoca (UK), Rightmove Commercial (UK), Objektvision (Sweden), Toimitilat.fi (Finland), Ejendomstorvet (Denmark), OfficeRentInfo (pan-EU).

### Legal

This actor scrapes only publicly visible listing data for lawful purposes such as market research. It does not collect personal data, does not bypass any login, and respects reasonable request rates. You are responsible for how you use the data.

# Actor input Schema

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

Italian comune (e.g. 'Milano', 'Torino', 'Sesto San Giovanni') or a province as 'provincia-XX' with the two-letter code (e.g. 'provincia-mi' for the whole province of Milan). The site requires a location — when this is left empty the actor searches Milano.

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

Rent (affitto) or sale (vendita).

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

Commercial segment as Commerciali.it defines them. 'All commercial' returns every segment. Note: the portal has no separate land segment; 'aziende-agricole' (farm estates) is the closest.

## `minPrice` (type: `integer`):

Only listings priced at or above this amount. The site filters on the raw number as quoted by the agency (rent quotes mix monthly and annual figures — see the README).

## `maxPrice` (type: `integer`):

Only listings priced at or below this amount. The site filters on the raw number as quoted by the agency.

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

Maximum number of listings to return. Hard cap for the run — the whole portal holds over 100,000 listings; a single province search can return several thousand.

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

Proxy settings. Commerciali.it sits behind Cloudflare (verified in recon, docs/site-recon/commerciali-it.md) — Italian residential proxy is the reliable default.

## Actor input object example

```json
{
  "searchQuery": "milano",
  "listingType": "rent",
  "segment": "all",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IT"
  }
}
```

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

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

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/commerciali-it-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": "milano",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "IT"
  }
}' |
apify call studio-amba/commerciali-it-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/commerciali-it-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/0hxsHqbpifKkckNbe/builds/FSGDAkm2kjY7LaWJz/openapi.json
