# France Real Estate Scraper ($1.50/1K) (`carabain-digital/france-real-estate`) Actor

Search SeLoger, Bien'ici and PAP at once for annonces immobilières in France: appartements and maisons, location or vente. One search, one dataset, merged and newest first. Optional full details and price history. Residential proxy included. JSON, CSV or Excel.

- **URL**: https://apify.com/carabain-digital/france-real-estate.md
- **Developed by:** [Carabain Digital](https://apify.com/carabain-digital) (community)
- **Categories:** Real estate, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.90 / 1,000 listings

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What is France Real Estate Scraper?

**France Real Estate Scraper** searches **three property portals in France with one query** (SeLoger, Bien'ici and PAP) and returns one clean dataset of annonces immobilières (appartements and maisons, location or vente): **merged and sorted newest first**. Export as JSON, CSV or Excel. Costs **$1.50 per 1,000 listings**; full details are an add-on at $2 per 1,000 and price history at $1 per 1,000. A French residential proxy is built in.

- 🌍 **3 sites, one run**: SeLoger, Bien'ici and PAP are searched in parallel (about 20 seconds for 60 listings)
- 🧹 **Cross-site dedup**: the same home on several portals (same postcode, house number and listing type) appears once, with an `also_on` list of the other sites. See below why this rarely fires in France
- 📅 **Newest first** across all sites, with a total **Max listings** cap and an optional cap per site
- 🎯 **Pick the sites** you want under **Sites**
- 🛡️ **A blocked or failing site never fails the run**: it is retried on a fresh proxy session, then skipped and logged; the others still deliver
- 📈 **Optional price history**: the same shared store as our single-site Actors
- 🤖 **Agent friendly**: one flat schema for all sites, works through the Apify MCP server

#### Which sites are included?

| Site | Country | Single-site Actor | Default | Notes |
|---|---|---|---|---|
| [SeLoger](https://www.seloger.com) | France | [seloger-listings](https://apify.com/carabain-digital/seloger-listings) | yes | Largest French portal, at most 10,000 results per search; DataDome protected, so a few proxy exits are refused and retried; French residential proxy needed |
| [Bien'ici](https://www.bienici.com) | France | [bienici-listings](https://apify.com/carabain-digital/bienici-listings) | yes | Agencies and private sellers, at most 2,500 results per search; fast |
| [PAP](https://www.pap.fr) | France | [pap-listings](https://apify.com/carabain-digital/pap-listings) | yes | Particulier à particulier (private sellers), about 300-375 results per search; **only searches inside a place**; French residential proxy needed |

**Results per site are capped by each site, not by this Actor** (SeLoger 10,000, Bien'ici 2,500, PAP 300-375 per search). Asking for more returns what the site offers.

#### What data can I extract?

<table>
<tr><td>🆔 Stable listing ID, source site and URL</td><td>💶 Asking price or monthly rent</td></tr>
<tr><td>📍 Address, postcode, city, department, region</td><td>🏠 Property type, listing type and status</td></tr>
<tr><td>📐 Living area and plot area</td><td>🛏 Rooms (pièces), bedrooms, bathrooms</td></tr>
<tr><td>⚡ DPE energy label</td><td>📅 Date listed</td></tr>
<tr><td>🧑‍💼 Agency name, phone and link (where the site shows them)</td><td>🖼 Photos</td></tr>
<tr><td>🔁 <code>also_on</code>: other sites with the same home</td><td>📖 Description, coordinates, build year, charges (add-on)</td></tr>
</table>

Every site fills what it has; the rest is `null`. Site-specific extras (for example `price_includes_charges`, `rent_excl_charges` and `department` from SeLoger, `old_price` from Bien'ici and PAP) are kept as extra fields.

#### How do I scrape French real estate?

1. [Create a free Apify account](https://console.apify.com/sign-up) and open this Actor.
2. Enter a **Location** (for example `Lyon`) and choose **For sale** (vente) or **For rent** (location).
3. Optionally set price, property type, rooms, living area and **Max listings**.
4. Optionally change **Sites**, and switch on **Full details** and/or **Price history**.
5. Click **Start** and download the listings from the **Output** tab as JSON, CSV, Excel, XML or HTML.

### How much does it cost to scrape French property sites?

You **pay per home** that ends up in your dataset: **$1.50 per 1,000 unique listings**, after duplicates are removed. No subscription, the proxy is included.

- **Add-on: Full details, $2.00 per 1,000** listings, **off by default**. Charged only for listings that were actually enriched. One price for all three sites.
- **Add-on: Price history, $1.00 per 1,000** listings, **off by default**. Charged only for listings that already had history (the first run is free).
- The monthly credit of Apify's free plan covers thousands of listings.
- You are charged for the listings in the dataset, not for the (more numerous) listings fetched before deduplication and the **Max listings** cut. Set a maximum cost per run in the run options.

### Input

See the **Input** tab for all options. The shared fields are the same as in our single-site real-estate Actors, except Start URLs (they are site-specific: for those use the single-site Actors).

| Field | Description |
|---|---|
| **Location** (`location`) | City, arrondissement, department or postcode, sent to every selected site. Commas run separate searches |
| **Listing type** (`listing_type`) | `sale` (default) or `rent` |
| **Min / Max price** (`min_price`, `max_price`) | Asking price, or rent per month, in euro |
| **Property type** (`property_type`) | `any`, `house`, `apartment`, `land`, `commercial`, `parking` |
| **Min rooms** (`min_rooms`) | At least this many rooms (pièces) |
| **Min living area** (`min_living_area_m2`) | At least this many m2 |
| **Sites** (`sites`) | `seloger`, `bienici`, `pap` (default: all three) |
| **Max listings** (`limit`) | Cap on the merged dataset; every site gets a fair share |
| **Max listings per site** (`limit_per_site`) | Optional cap per site (default: Max listings) |
| **Full details** (`includeDetails`) | Paid add-on: detail page data |
| **Price history** (`trackHistory`, `historyStoreName`) | Paid add-on: history in your own named store |
| **Proxy** (`proxyConfiguration`) | Apify RESIDENTIAL, country FR by default; the Actor applies it only to the sites that need it |

Example input:

```json
{
    "location": "Lyon",
    "listing_type": "rent",
    "max_price": 1200,
    "limit": 100
}
```

#### Location

All sites are in France, so one location works everywhere. The Actor sends it to **every selected site as is**:

- **Several places**: a comma list runs one search per place on every site (the per-site limit is divided over the places). A place that a site rejects is skipped for that site.
- **PAP only searches inside a place.** Without a location, PAP is skipped and SeLoger and Bien'ici return listings for all of France.
- If **every** selected site rejects the input, the run fails with an input error so you notice.

### Output

Listings are stored in the default dataset, one item per unique home. Export them as JSON, CSV, Excel, XML or HTML. Every site uses the same field names (`id` is `<source>:<site id>`). Example (shortened):

```json
{
    "id": "bienici:example-123456",
    "source": "bienici",
    "url": "https://www.bienici.com/annonce/vente/lyon-69003/appartement/3pieces/example-123456",
    "title": "Appartement 3 pièces 68 m2",
    "listing_type": "sale",
    "property_type": "apartment",
    "status": "available",
    "price": 289000,
    "price_currency": "EUR",
    "price_period": null,
    "postcode": "69003",
    "city": "Lyon",
    "country": "FR",
    "living_area_m2": 68,
    "rooms": 3,
    "listed_at": "2026-10-31T08:12:00Z",
    "scraped_at": "2026-11-01T09:00:01Z",
    "also_on": []
}
```

(shortened; all real-estate fields are present, `null` when the site has none. Values above are illustrative.) `status` is `available`, `under_offer`, `sold` or `rented`.

#### How duplicates are removed

Two listings are the same home when they have the same **postcode**, **house number (with addition)** and **listing type** (sale or rent), on different sites. The first one is kept (order: SeLoger, Bien'ici, PAP) and the other sites go in `also_on`. **None of the three French portals publish house numbers**, so almost no listing qualifies and cross-site duplicates are rarely merged: the same flat can appear once per portal, especially when an agency posts it on SeLoger and Bien'ici. Listings without postcode or house number are never merged, and two listings of the same site are never merged (flats in one building). PAP is mostly private sellers, so it overlaps less with the other two.

#### Sorting

With **Max listings**, every site gets a fair share: listings are taken in turns from each site (each in its own newest-first order). The result is then sorted newest first by `listed_at`; items without a date keep their site order. PAP search results carry no date; the Full details add-on adds it.

#### Rent: with or without charges

SeLoger rents mostly **include charges** (charges comprises); `price_includes_charges` says which, and `rent_excl_charges` gives the rent without charges with the Full details add-on. PAP shows rents charges included too, Bien'ici shows them excluded, so compare rents per site with care.

#### Price history: track price and status changes

Switch on **Price history** (`trackHistory`) to follow listings over time. The Actor keeps a small history record per listing in a **named key-value store in your own Apify account** (default name `realestate-history`; change it with `historyStoreName`). We run no database and hold none of your data.

- **Shared with the single-site Actors.** Our single-site real-estate Actors use the same default store name and listing IDs, so a listing tracked there continues its series here, and the other way round.
- **The first run starts the series.** Listings seen for the first time are not charged for the add-on.
- **Every later run** adds `first_seen_at`, `previous_price`, `price_change`, `price_change_pct`, `status_changed` and `price_history` (the last 20 points) to each listing you saw before.
- **History runs once over the merged list**, after deduplication.
- **Do not run two runs on the same store at the same time**: the last writer wins per record. If you delete the store, history silently starts empty.

### What can I do with French real estate data?

- 📈 **Market research**: compare prix au m2 and rents per city, arrondissement and portal
- 🔔 **Alerts and feeds**: new annonces and price drops to Slack, e-mail or your own site
- 🏢 **Investors and agents**: find new listings, spot private sellers on PAP, benchmark competitors
- 🧠 **AI and analytics**: feed listing data into valuation models

### Tips for best results

- Bien'ici is the fastest (under a second for 60 listings); SeLoger needs a few seconds and sometimes a retry on a fresh proxy exit, which the Actor does for you; PAP is slowest (about 20 seconds for 60 listings).
- Always give a **Location** if you want PAP in the result.
- For a daily feed, schedule a run with a high **Max listings** and **Price history** on.
- Need a search URL you built on one site? Use that site's own Actor ([seloger-listings](https://apify.com/carabain-digital/seloger-listings), [bienici-listings](https://apify.com/carabain-digital/bienici-listings), [pap-listings](https://apify.com/carabain-digital/pap-listings)); this Actor takes filters, not URLs.

### Frequently asked questions

#### Can I use France Real Estate Scraper with the Apify API?

Yes. Use the [Apify API](https://docs.apify.com/api/v2) or the Apify clients. Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("carabain-digital/france-real-estate").call(run_input={"location": "Lyon", "listing_type": "rent", "max_price": 1200, "limit": 100})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["source"], item["title"])
```

#### Can I use France Real Estate Scraper through an MCP server or with AI agents?

Yes. Add the [Apify MCP server](https://mcp.apify.com) to your AI agent (Claude, ChatGPT, Cursor and others) and let it call `carabain-digital/france-real-estate` with `call-actor`. The input is small and every field has a description, so an agent can fill it from a request such as "find the 20 newest appartements for rent in Lyon" (`location`, `listing_type`, `property_type`, `limit`). A small run finishes in seconds; the agent then reads the dataset with `get-dataset-items`. Add-ons are off by default, so an agent pays only the base price unless it asks for more.

#### Can I integrate the data with other apps?

Yes: Make, Zapier, Google Sheets, Slack, Airbyte and webhooks, via Apify's [integrations](https://apify.com/integrations).

#### Why are there fewer listings than Max listings?

Each site returns what matches your search, duplicates across sites are removed, and sites that do not know a filter are skipped. PAP is skipped without a location and has a ceiling of about 300-375 results per search. A narrow search can leave you with fewer.

#### Why do I see the same home twice?

SeLoger, Bien'ici and PAP do not publish house numbers, so the Actor cannot tell with certainty that two listings are the same home and keeps both. Compare on `postcode`, `living_area_m2`, `rooms` and `price` if you need to merge them yourself.

#### Why does one site return nothing?

Either it has no match for your search, or it was blocked and skipped after retries. The run log lists skipped sites. If **all** selected sites fail, the run fails so you notice. Try again later or open an issue.

#### Is it legal to scrape property portals?

The Actor only collects publicly visible listing data. Listings can contain personal data (for example an agent's or private seller's name or phone number), and rules such as GDPR may apply to how you store and use it. Check your use case with a lawyer. See also [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

#### France Real Estate Scraper not working? / Feedback

Open an issue in the **Issues** tab of this Actor with the run link and the input you used; I usually answer within a few days.

### Other scrapers by us

The three single-site Actors behind this one are linked in the table above: [seloger-listings](https://apify.com/carabain-digital/seloger-listings), [bienici-listings](https://apify.com/carabain-digital/bienici-listings), [pap-listings](https://apify.com/carabain-digital/pap-listings). They are cheaper per home when you need one site only, and take search URLs.

⭐ **Does it work well for you?** A review on the Store page helps others find this Actor and helps us keep it maintained.

# Actor input Schema

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

French city, arrondissement, department or postcode, sent to all sites. Several places separated by commas run as separate searches. Example: `Lyon`, `Paris 15e, Nice` or `69003`. PAP only searches inside a place: without a location PAP is skipped. Leave empty for all of France on SeLoger and Bien'ici.

## `listing_type` (type: `string`):

Search homes `rent` or `sale`. Example: `rent`.

## `min_price` (type: `integer`):

Lowest asking price in euro (rent per month; SeLoger and PAP show rent charges included, Bien'ici excluded). Example: `800` (rent) or `200000` (sale).

## `max_price` (type: `integer`):

Highest asking price in euro (rent per month). Example: `1500` (rent) or `450000` (sale).

## `property_type` (type: `string`):

Only this type of property. Example: `apartment`. `any` returns every type the sites list (SeLoger: houses and apartments).

## `min_rooms` (type: `integer`):

Only homes with at least this many rooms (pièces, a studio counts 1). Example: `3`.

## `min_living_area_m2` (type: `integer`):

Only homes with at least this living area in square metres. Example: `60`.

## `sites` (type: `array`):

Which sites to search. Default: all of them. Example: `["seloger", "bienici", "pap"]`.

## `limit` (type: `integer`):

Cap on the merged dataset, newest first. Example: `100`. Each site has its own ceiling: SeLoger 10,000, Bien'ici 2,500 and PAP about 300-375 results per search.

## `limit_per_site` (type: `integer`):

Optional cap per site, to keep the mix balanced and browser sites short. Default: Max listings. Example: `25`.

## `includeDetails` (type: `boolean`):

Also open each listing's page on the selected sites: full description, coordinates (when the exact address is public), rent without charges, deposit, DPE values, agency contact and all photos. Adds $2.00 per 1,000 listings that were actually enriched. Runs take a little longer.

## `trackHistory` (type: `boolean`):

Keep a price and status history per listing in a named storage in your own account and add `first_seen_at`, `previous_price`, `price_change`, `price_change_pct`, `status_changed` and `price_history` to every listing you have scraped before. The history store is shared with our single-site real-estate Actors. Adds $1.00 per 1,000 listings that already had history (the first run only starts the series). Do not run two runs on the same store at once.

## `historyStoreName` (type: `string`):

Name of the key-value store that holds the history (a-z, 0-9 and dashes). Use the same name in all our real-estate Actors to share one history. Example: `realestate-history`.

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

Keep Apify RESIDENTIAL, country FR (the default). SeLoger and PAP block datacenter IPs; Bien'ici does not need the proxy but gets it too. The Actor applies it where needed.

## Actor input object example

```json
{
  "location": "Lyon",
  "listing_type": "sale",
  "property_type": "any",
  "sites": [
    "seloger",
    "bienici",
    "pap"
  ],
  "limit": 20,
  "includeDetails": false,
  "trackHistory": false,
  "historyStoreName": "realestate-history",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

All listings from the selected sites, merged and deduplicated, newest first.

# 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": "Lyon",
    "listing_type": "sale",
    "sites": [
        "seloger",
        "bienici",
        "pap"
    ],
    "limit": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "FR"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("carabain-digital/france-real-estate").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": "Lyon",
    "listing_type": "sale",
    "sites": [
        "seloger",
        "bienici",
        "pap",
    ],
    "limit": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "FR",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("carabain-digital/france-real-estate").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 '{
  "location": "Lyon",
  "listing_type": "sale",
  "sites": [
    "seloger",
    "bienici",
    "pap"
  ],
  "limit": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "FR"
  }
}' |
apify call carabain-digital/france-real-estate --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,carabain-digital/france-real-estate"
        }
    }
}
```

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/XmwUCS838VaR8SNz0/builds/JhHcuhIjYBVpuy85x/openapi.json
