Find the best rental investment properties across France's top real estate platforms.
Scans 7 major listing sites, estimates rental yield, scores each property, and exports a ranked Excel report.
- Prerequisites
- Windows Setup
- Linux Setup
- How It Works
- Usage
- Configuration
- Scoring System
- Excel Output
- Supported Sites
- Anti-Bot Bypass
- Build From Source
Windows, step by step
- Go to https://www.python.org/downloads/
- Click the big yellow "Download Python 3.12.x" button
- Run the installer
- IMPORTANT: Check the box "Add Python to PATH" at the bottom of the first screen
- Click "Install Now"
- When done, open a terminal (press
Win + R, typecmd, press Enter) and verify:You should seepython --versionPython 3.12.x. If you see an error, restart your computer and try again.
Linux (Ubuntu/Debian)
sudo apt update
sudo apt install python3 python3-venv python3-pip git
python3 --version # should show 3.12+macOS
brew install python@3.12 git
python3 --version-
Download the project:
- Click the green "Code" button at the top of this page
- Click "Download ZIP"
- Extract the ZIP somewhere (e.g. your Desktop)
Or if you have Git:
git clone https://github.com/mattow02/immo-scanner.git -
Open the extracted folder and double-click
setup-and-run.bat- First run: installs everything, opens
.envin Notepad for you to configure - Next runs: launches the interactive scanner directly
- First run: installs everything, opens
-
Follow the prompts: pick cities, budget, sites, done.
The Excel report is saved in the output/ folder.
If you want a portable executable that works without Python:
- Double-click
build-windows.bat - Wait for the build to finish (~2 minutes)
- Your executable is at
dist\immo-scanner.exe - Copy
immo-scanner.exe+ your.envfile anywhere and run it
git clone https://github.com/mattow02/immo-scanner.git
cd immo-scanner
python -m venv venv
venv\Scripts\activate
pip install -e .
copy .env.example .env
notepad .env
immo-scanner| Problem | Fix |
|---|---|
python is not recognized |
Reinstall Python, check "Add Python to PATH" |
pip is not recognized |
Run python -m pip install -e . instead |
| Red text / encoding errors | Run chcp 65001 before launching (enables UTF-8) |
| Excel won't open | Check the output/ folder, file is named resultats_immo_YYYYMMDD_HHMMSS.xlsx |
curl_cffi install fails |
Install Visual C++ Build Tools |
curl -LO https://github.com/mattow02/immo-scanner/releases/latest/download/immo-scanner-linux
chmod +x immo-scanner-linux
curl -LO https://raw.githubusercontent.com/mattow02/immo-scanner/main/.env.example
mv .env.example .env
nano .env
./immo-scanner-linuxgit clone https://github.com/mattow02/immo-scanner.git
cd immo-scanner
python3 -m venv venv
source venv/bin/activate
pip install -e .
cp .env.example .env
nano .env
immo-scannerLeBonCoin and SeLoger work out of the box. For Laforet, Orpi, and Figaro, also run:
pip install playwright playwright-stealth
playwright install chromium You run immo-scanner
|
v
+-----------------+ +-----------------+ +------------------+
| Scrape listings |---->| Score & rank |---->| Export Excel |
| from 7 sites | | by yield, price | | 3 tabs, links, |
| (API + browser) | | demand, type... | | colors, stats |
+-----------------+ +-----------------+ +------------------+
|
Filters out:
- Viager (life annuities)
- Managed residences / EHPAD
- Caves, parkings, garages
- Suspicious price/m2 anomalies
- Duplicates across sites
Run immo-scanner with no arguments:
Step 1/6: Target cities
Step 2/6: Budget range
Step 3/6: Property types
Step 4/6: Listing sites
Step 5/6: Yield & options
Step 6/6: Summary → Start scan? [Y/n]
immo-scanner scan --city Lyon --budget-max 150000 --min-yield 7
immo-scanner scan --city Paris --city Marseille --city Bordeaux
immo-scanner scan --sites leboncoin --city Strasbourg --no-excel
immo-scanner config
immo-scanner sites| Flag | Description | Example |
|---|---|---|
--city |
City to scan (repeatable) | --city Lyon --city Paris |
--department |
Department code (repeatable) | --department 69 |
--budget-min |
Minimum price (EUR) | --budget-min 50000 |
--budget-max |
Maximum price (EUR) | --budget-max 150000 |
--surface-min |
Minimum area (m2) | --surface-min 20 |
--surface-max |
Maximum area (m2) | --surface-max 80 |
--types |
Property types | --types apartment,house |
--min-yield |
Minimum gross yield (%) | --min-yield 6 |
--sites |
Sites to scrape | --sites leboncoin,seloger |
--max-pages |
Max pages per site per city | --max-pages 3 |
--rental-mode |
Rent estimation mode | --rental-mode avg_price |
-o, --output |
Output directory for Excel | -o ./results |
--no-excel |
Terminal display only | --no-excel |
-v, --verbose |
Verbose logging |
Copy .env.example to .env and edit:
IMMO_CITIES=Lyon,Marseille,Bordeaux # Target cities
IMMO_BUDGET_MIN=30000 # Min price (EUR)
IMMO_BUDGET_MAX=200000 # Max price (EUR)
IMMO_SURFACE_MIN=15 # Min area (m2)
IMMO_TYPES=apartment,house,building # Property types
IMMO_RENTAL_MODE=both # avg_price | cross_ref | both
IMMO_MIN_YIELD=5.0 # Min gross yield (%)
IMMO_SITES=leboncoin,seloger # Sites to use
IMMO_MAX_PAGES=3 # Pages per site per city
IMMO_OUTPUT_DIR=./output # Excel output folder| Mode | Speed | Accuracy | Description |
|---|---|---|---|
avg_price |
Fast | Medium | Built-in rent/m2 database for 50+ French cities |
cross_ref |
Slow | High | Scrapes actual rental listings to estimate real market rent |
both |
Medium | Best | Combines both methods (default) |
Each property gets a score from 0 to 100:
| Criterion | Weight | What it measures |
|---|---|---|
| Gross yield | 40% | (monthly rent x 12) / price x 100 |
| Price/m2 vs city avg | 15% | Below average = good deal |
| Rental demand | 15% | Local supply/demand tension |
| Property type | 10% | Studios & T2 score higher (easier to rent) |
| Size coherence | 10% | Area must match room count |
| Listing freshness | 10% | Recent listings score higher |
The .xlsx file has 3 tabs:
| Tab | Content |
|---|---|
| Ranking | Properties sorted by score with links |
| Details | Full data: description, rooms, DPE, GPS, score breakdown |
| Statistics | Summary: count, avg/median yield, top cities, sources |
Color coding: green (yield >= 8%), orange (5-8%), red (< 5%).
| Site | Method | Needs Playwright? | Status |
|---|---|---|---|
| LeBonCoin | JSON API + TLS impersonation | No | Fully working |
| SeLoger | HTML + TLS impersonation | No | Fully working |
| Bien'ici | Browser rendering | Yes | Working |
| Laforet | Browser rendering | Yes | Working |
| Orpi | Browser rendering | Yes | Working |
| Figaro Immo | Browser rendering | Yes | Working |
| PAP | Browser rendering | Yes | Partial |
1. TLS Fingerprinting (LeBonCoin, SeLoger) : curl_cffi impersonates Chrome's TLS handshake signature. DataDome can't tell the difference. No captcha needed.
2. Headless Browser (Bien'ici, Laforet, Orpi) : Real Chromium with playwright-stealth patches.
The scoring core is pure logic: rent estimation, yield, ranking and deduplication import nothing from the network, the browser, or any third-party package. That is what makes them testable in isolation, and they are:
pip install -r requirements-dev.txt
pytest tests -q # 19 tests, ~0.03sThey run on every push in continuous integration.
Linux:
source venv/bin/activate
pip install pyinstaller
python build.py
# Output: dist/immo-scannerWindows: double-click build-windows.bat, or:
venv\Scripts\activate
pip install pyinstaller
python build.py
# Output: dist\immo-scanner.exeThis tool is for personal use and educational purposes only. Scraping may violate the terms of service of some websites. Use responsibly and respect rate limits.
MIT