# French Real Estate Scraper — Bien'ici, LeBonCoin & SeLoger (`apikiy/french-realestate`) Actor

Configure the scraper for French real estate listings from Bien'ici (API, no proxy needed), LeBonCoin (requires proxy), and SeLoger (requires proxy).

- **URL**: https://apify.com/apikiy/french-realestate.md
- **Developed by:** [Julien ApiKiy](https://apify.com/apikiy) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

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

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## 🏠 French Real Estate Scraper — Immobilier France

[![Apify Actor](https://apify.com/badge/actor.svg)](https://apify.com/french-realestate-scraper)

> Scrape French real estate listings from **Bien'ici** (primary) and **Trovit** (fallback) — no residential proxy required for Bien'ici.

### 🔍 What It Does

This Apify Actor scrapes property listings from French real estate platforms, extracts structured data, and outputs it for analysis, market research, or lead generation.

#### Supported Platforms
- **Bien'ici** — Modern property search platform with structured listings (primary target)
- **Trovit** — Aggregated real estate classifieds (fallback)

### 📋 Features

- **Bien'ici-first design** — Works from datacenter IPs without proxy (no Cloudflare)
- **Trovit fallback** — Automatically falls back to Trovit if Bien'ici has no results
- **Smart filtering** — Filter by city, property type, price range, rooms, and surface area
- **Rich data extraction** — Title, price, surface, rooms, bedrooms, address, city, zipCode, description, images, energy class (DPE), agency
- **French price parsing** — Handles '450 000 €', '1 200 €/mois', NB (non communiqué)
- **Property types** — Appartement and maison
- **Smart pagination** — Configurable pages per site with URL-based deduplication
- **Anti-detection** — Random delays (3-8s), session pooling, max 2 concurrent browsers
- **Detail page enrichment** — Visits individual listing pages for full descriptions and images
- **Optional proxy** — Built-in Apify proxy support for enhanced reliability

### 🏗️ Input Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `city` | string | Paris | Target city (e.g., 'Lyon', 'Marseille') |
| `propertyType` | string | appartement | `appartement` or `maison` |
| `minPrice` | integer | — | Minimum price in euros |
| `maxPrice` | integer | — | Maximum price in euros |
| `minRooms` | integer | — | Minimum number of rooms |
| `maxRooms` | integer | — | Maximum number of rooms |
| `minSurface` | integer | — | Minimum surface in m² |
| `maxSurface` | integer | — | Maximum surface in m² |
| `maxPages` | integer | 3 | Pages per site |
| `useProxy` | boolean | false | Enable Apify proxy |

### 📊 Output Data

Each listing includes:

```json
{
  "title": "Appartement T3 Paris 15ème",
  "price": 450000,
  "surface": 65,
  "rooms": 3,
  "bedrooms": 2,
  "address": "15 rue de Rivoli, 75001 Paris",
  "city": "Paris",
  "zipCode": "75001",
  "source": "bienici",
  "url": "https://www.bienici.com/annonces/achat/...",
  "images": ["https://res.bienici.com/...jpg"],
  "description": "Bel appartement avec vue sur la tour Eiffel...",
  "energyClass": "C",
  "agency": "Century 21 Paris",
  "scrapedAt": "2026-07-04T12:00:00.000Z"
}
````

### 🚀 Usage

#### On Apify Platform

1. Go to [Apify Console](https://console.apify.com/)
2. Search for "French Real Estate Scraper"
3. Click **Try actor**
4. Fill in the input form (city, filters, etc.)
5. Click **Start**

#### Via API

```bash
curl -X POST "https://api.apify.com/v2/acts/french-realestate-scraper/runs" \
  -H "Content-Type: application/json" \
  -d '{
    "city": "Paris",
    "propertyType": "appartement",
    "minPrice": 200000,
    "maxPrice": 500000,
    "minRooms": 2,
    "maxPages": 5
  }'
```

#### Locally

```bash
## Clone the repository
git clone https://github.com/your-org/french-realestate-scraper.git
cd french-realestate-scraper

## Install dependencies
npm install

## Run tests
npm test

## Run locally (requires APIFY_TOKEN environment variable)
node src/main.js
```

### 🔧 Technical Details

- **Crawler**: PlaywrightCrawler (headless Chromium)
- **Concurrency**: Max 2 concurrent browsers
- **Session Pool**: 30 sessions with auto-retirement on blocks
- **Request Delay**: Random 3-8 seconds between requests
- **Deduplication**: URL-based dedup across all sites
- **Error Handling**: Captcha detection, session retirement, retry logic
- **Crawlee**: v3.12+ (valid options only — no throwOnBlockedRequest, maxUsageSecs, etc.)

### 🛡️ Anti-Detection Features

- Random delays between requests (3-8 seconds)
- Session pool with automatic retirement on blocks
- Browser fingerprint rotation
- Configurable proxy support (residential/datacenter)

### 📦 Dependencies

- [Apify SDK](https://www.npmjs.com/package/apify) — Apify runtime
- [Crawlee](https://www.npmjs.com/package/crawlee) — Web crawling framework
- [Playwright](https://www.npmjs.com/package/playwright) — Browser automation
- [JSDOM](https://www.npmjs.com/package/jsdom) — DOM testing (dev)

### 🐳 Docker

```bash
## Build
docker build -t french-realestate-scraper .

## Run
docker run -e APIFY_TOKEN=your_token french-realestate-scraper
```

### 💰 Pricing

Pay-per-use, no monthly fees:

| | Price |
|---|---|
| **Actor start** | $0.01 |
| **Per result** | $0.001 |

> 💡 Example: A run returning 500 results costs **$0.51** total ($0.01 start + 500 × $0.001).

### 📄 License

MIT License

***

**Keywords**: immobilier, France, scraping, real estate, apartment, house, property, Bienici, Trovit, French property, immobilier France, real estate scraper, property listings, Paris real estate, Lyon property, Marseille immobilier, French apartments, maison France, DPE, energy rating, property search France

# Actor input Schema

## `city` (type: `string`):

Target city for property search (e.g., 'Paris', 'Lyon', 'Marseille')

## `source` (type: `string`):

Which site to scrape. Bien'ici uses a public API (no proxy). LeBonCoin and SeLoger require residential proxy (set useProxy=true + APIFY\_PROXY\_PASSWORD).

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

Type of property to search for

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

Minimum price in euros. Leave empty for no minimum.

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

Maximum price in euros. Leave empty for no maximum.

## `minRooms` (type: `integer`):

Minimum number of rooms (pièces)

## `maxRooms` (type: `integer`):

Maximum number of rooms (pièces)

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

Minimum surface area in square meters

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

Maximum surface area in square meters

## `maxPages` (type: `integer`):

Maximum number of listing pages to scrape per site

## `useProxy` (type: `boolean`):

Enable Apify proxy. REQUIRED for LeBonCoin and SeLoger. Optional for Bien'ici (works without proxy).

## Actor input object example

```json
{
  "city": "Paris",
  "source": "bienici",
  "propertyType": "appartement",
  "maxPages": 3,
  "useProxy": false
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("apikiy/french-realestate").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("apikiy/french-realestate").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 '{}' |
apify call apikiy/french-realestate --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "French Real Estate Scraper — Bien'ici, LeBonCoin & SeLoger",
        "description": "Configure the scraper for French real estate listings from Bien'ici (API, no proxy needed), LeBonCoin (requires proxy), and SeLoger (requires proxy).",
        "version": "0.1",
        "x-build-id": "lKNBvgXn2VrdJDTlM"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/apikiy~french-realestate/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-apikiy-french-realestate",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/apikiy~french-realestate/runs": {
            "post": {
                "operationId": "runs-sync-apikiy-french-realestate",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/apikiy~french-realestate/run-sync": {
            "post": {
                "operationId": "run-sync-apikiy-french-realestate",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "city"
                ],
                "properties": {
                    "city": {
                        "title": "City",
                        "type": "string",
                        "description": "Target city for property search (e.g., 'Paris', 'Lyon', 'Marseille')",
                        "default": "Paris"
                    },
                    "source": {
                        "title": "Data Source",
                        "enum": [
                            "bienici",
                            "leboncoin",
                            "seloger",
                            "all"
                        ],
                        "type": "string",
                        "description": "Which site to scrape. Bien'ici uses a public API (no proxy). LeBonCoin and SeLoger require residential proxy (set useProxy=true + APIFY_PROXY_PASSWORD).",
                        "default": "bienici"
                    },
                    "propertyType": {
                        "title": "Property Type",
                        "enum": [
                            "appartement",
                            "maison"
                        ],
                        "type": "string",
                        "description": "Type of property to search for",
                        "default": "appartement"
                    },
                    "minPrice": {
                        "title": "Minimum Price (€)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum price in euros. Leave empty for no minimum."
                    },
                    "maxPrice": {
                        "title": "Maximum Price (€)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum price in euros. Leave empty for no maximum."
                    },
                    "minRooms": {
                        "title": "Minimum Rooms",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Minimum number of rooms (pièces)"
                    },
                    "maxRooms": {
                        "title": "Maximum Rooms",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum number of rooms (pièces)"
                    },
                    "minSurface": {
                        "title": "Minimum Surface (m²)",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Minimum surface area in square meters"
                    },
                    "maxSurface": {
                        "title": "Maximum Surface (m²)",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Maximum surface area in square meters"
                    },
                    "maxPages": {
                        "title": "Max Pages per Site",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Maximum number of listing pages to scrape per site",
                        "default": 3
                    },
                    "useProxy": {
                        "title": "Use Proxy",
                        "type": "boolean",
                        "description": "Enable Apify proxy. REQUIRED for LeBonCoin and SeLoger. Optional for Bien'ici (works without proxy).",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
