# SeLoger Bureaux & Commerces Scraper — Offices, Shops, Land (`studio-amba/seloger-bureaux-commerces-scraper`) Actor

Scrape French commercial real estate from SeLoger Bureaux & Commerces: offices, shops, warehouses, coworking and land for rent or sale. Rents in EUR/m2/year, surfaces, locations with coordinates, agencies and photos. Search any French city, no login needed.

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

## Pricing

from $20.00 / 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.

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

## SeLoger Bureaux & Commerces Scraper

Extract commercial real estate listings from [seloger-bureaux-commerces.com](https://www.seloger-bureaux-commerces.com), the commercial arm of SeLoger, France's largest property portal. Around 30,000 active listings: bureaux (offices), boutiques and locaux commerciaux (retail), locaux d'activités and entrepôts (industrial), terrains (land) and coworking spaces, for rent or for sale, across every French city.

No login, no cookies, no API key. You give it a city, it returns structured JSON.

### Why use this actor

- **Rents in the standard French quote.** Commercial rents in France are quoted in EUR per m² per year. The actor returns that figure directly (`price` with `priceUnit: "EUR/m2/an"`), plus the monthly and yearly totals, so you can compare listings without recalculating.
- **Structured source data, not scraped text.** Listings come from the site's own data payload: exact surfaces, coordinates, INSEE codes, agency names, publication dates. No brittle CSS selectors over rendered HTML.
- **Any French commune.** Location input takes a city name, a postal code, or a SeLoger city code. Names are resolved through the official French government geo API.
- **Honest price handling.** Price on application is normal in commercial real estate. Those listings come through with `price: null` and `priceOnRequest: true` instead of a fake zero.

Typical uses: market rent studies per city or arrondissement, deal sourcing for investors and brokers, monitoring new supply in a segment, feeding valuation models with EUR/m²/an comparables, tracking agency inventory.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `searchQuery` | string | `Paris` | City name (`Paris`, `Bordeaux`, `Lille`), 5-digit postal code (`33000`), or 6-digit SeLoger city code (`750056`) |
| `listingType` | string | `rent` | `rent` (location), `sale` (vente) or `both` |
| `segment` | string | `any` | `office`, `retail`, `industrial`, `land`, `coworking` or `any` |
| `minSurface` | integer | none | Minimum floor area in m² |
| `maxSurface` | integer | none | Maximum floor area in m² |
| `maxResults` | integer | `100` | Cap on returned listings, up to 24,000 per query |
| `proxyConfiguration` | object | FR residential | Keep the default. The site is DataDome-protected and requires French residential IPs |

Example input, offices for rent in Paris:

```json
{
    "searchQuery": "Paris",
    "listingType": "rent",
    "segment": "office",
    "maxResults": 100
}
```

Example input, boutiques for sale in Bordeaux:

```json
{
    "searchQuery": "Bordeaux",
    "listingType": "sale",
    "segment": "retail",
    "maxResults": 50
}
```

### Output

One JSON object per listing. Key fields:

| Field | Example | Description |
|---|---|---|
| `title` | `"Bureau, 250 m²"` | Listing headline |
| `segment` | `"office"` | office, retail, industrial, land, coworking |
| `propertyType` | `"Bureau"` | The site's French property type |
| `listingType` | `"rent"` | rent or sale |
| `price` | `385.5` | Rentals: EUR/m²/year. Sales: total EUR. Null if on application |
| `priceUnit` | `"EUR/m2/an"` | Unit of `price` |
| `priceMonthly` | `8031` | Monthly rent in EUR (rentals) |
| `priceYearly` | `96375` | Yearly rent in EUR (rentals) |
| `surface` | `250` | Floor area in m² |
| `city` / `postalCode` | `"Paris"` / `"75008"` | Location |
| `district` | `"Champs-Elysées"` | Quartier |
| `latitude` / `longitude` | `48.8721` / `2.3010` | Coordinates |
| `agencyName` | `"CBRE"` | Listing broker |
| `isDivisible` | `true` | Space can be split |
| `isImmediatelyAvailable` | `true` | Available now |
| `publishedAt` / `updatedAt` | ISO dates | Listing lifecycle |
| `url` | `https://www.seloger-bureaux-commerces.com/annonces/location/bureau/paris-8eme-75008/123456789` | Detail page |

Full example record:

```json
{
    "id": "242926153",
    "title": "Local d'activités / Entrepôt",
    "segment": "industrial",
    "propertyType": "Local d'activités / Entrepôt",
    "listingType": "rent",
    "price": 77.16,
    "priceUnit": "EUR/m2/an",
    "currency": "EUR",
    "priceOnRequest": false,
    "priceMonthly": 2990,
    "priceYearly": 35880,
    "pricePerSquareMeter": 77.16,
    "pricePerSquareMeterUnit": "EUR/m2/an",
    "surface": 465,
    "isDivisible": false,
    "isImmediatelyAvailable": true,
    "address": "CROIX BLANDIN",
    "district": "",
    "city": "Cernay-lès-Reims",
    "postalCode": "51420",
    "department": "51",
    "latitude": 49.25564,
    "longitude": 4.12638,
    "agencyName": "CBRE Impact - Reims",
    "reference": "51_1557",
    "publishedAt": "2025-05-28T20:57:00",
    "updatedAt": "2025-10-16T21:05:00",
    "url": "https://www.seloger-bureaux-commerces.com/annonces/location/local-d-activites-entrepot/cernay-les-reims-51420/242926153",
    "source": "seloger-bureaux-commerces",
    "scrapedAt": "2026-08-18T09:00:00.000Z"
}
```

### How to scrape SeLoger Bureaux & Commerces data

1. Open the actor on Apify and press **Try for free**.
2. Enter a French city in `searchQuery`, for example `Lyon` or the postal code `69003`.
3. Pick `listingType` (`rent` or `sale`) and a `segment`, for example `office` for bureaux.
4. Press **Start**. The run fetches search result pages (60 listings per page) and stops at `maxResults`.
5. Export the dataset as JSON, CSV or Excel from the **Storage** tab, or pull it through the Apify API.

The same works from code with the Apify client libraries for JavaScript and Python; pass the input object shown above.

### Pricing and cost per result

The actor charges per result (pay per event). One search page load returns up to 60 listings, so runs are short: a 100-listing run typically takes one to two minutes. Residential proxy traffic is kept low because images, fonts and media are never downloaded.

Note that a run's usage cost only settles after the run reaches the SUCCEEDED state; the figure shown while the run is still going is not final.

### Limitations

- One query covers one commune (plus the site's own nearby extensions). Paris, Lyon and Marseille are searched across all their arrondissements automatically. For a national sweep, loop the actor over a city list.
- A single search is capped by the site at 400 pages of 60 listings (24,000 rows). Narrow by segment or surface range if a market is larger.
- Price on application listings have `price: null`. That is the advertiser's choice, not missing data; `priceOnRequest` is `true` on those rows.
- Detail-page extras (DPE, foot traffic scores, divisibility tables) are not included; the actor reads search result data. Open an issue if you need detail enrichment.
- The site is protected by DataDome. The default French residential proxy configuration handles this; changing it to datacenter proxies will get the run blocked.

### FAQ

**Does it cover all of France?** Yes. Any commune the site serves, from Paris arrondissements to small towns, resolved by name or postal code.

**Why are rents per m² per year?** That is how French commercial real estate quotes rents. The monthly and yearly totals are included as separate fields.

**Can I get both rentals and sales in one run?** Yes, set `listingType` to `both`. Each row carries its own `listingType`.

**Is this legal?** The actor reads publicly available listing pages, the same data any visitor sees. No login, no personal accounts, no paywalled content.

**How fresh is the data?** Each run scrapes live. `publishedAt` and `updatedAt` tell you the listing's own lifecycle.

# Actor input Schema

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

French city to search: a city name ('Paris', 'Bordeaux', 'Lyon'), a 5-digit postal code ('33000'), or a 6-digit SeLoger city code ('750056'). City names are resolved to INSEE codes via the public geo.api.gouv.fr API. If empty, the actor searches Paris.

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

Rent (location), sale (vente) or both.

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

Commercial segment to filter on. 'Any' returns every segment. Retail covers both 'boutique' and 'local commercial'; industrial is 'local d'activités / entrepôt'.

## `minSurface` (type: `integer`):

Only return listings with at least this floor area, in square meters.

## `maxSurface` (type: `integer`):

Only return listings with at most this floor area, in square meters.

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

Maximum number of listings to return. The site serves 60 listings per page and caps a single search at 400 pages, so one query can return at most 24,000 listings. Narrow the segment or surface range to cover more of a large market.

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

The site is DataDome-protected; French RESIDENTIAL proxy is required (see docs/site-recon/seloger-bureaux-commerces.md). Datacenter IPs get an immediate CAPTCHA.

## Actor input object example

```json
{
  "searchQuery": "Paris",
  "listingType": "rent",
  "segment": "office",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}
```

# 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": "Paris",
    "listingType": "rent",
    "segment": "office",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "FR"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/seloger-bureaux-commerces-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": "Paris",
    "listingType": "rent",
    "segment": "office",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "FR",
    },
}

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/seloger-bureaux-commerces-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/8CpA8JN4Oo5SlkqDF/builds/lD2RrgN0LrhYtaS6U/openapi.json
