If you've tried to scrape Leboncoin or SeLoger (two of France's biggest sites), you've met DataDome — and probably lost. Here's what I found after actually shipping it, including the parts nobody says out loud.
The wall: DataDome guards everything
First myth to kill: there's no clever back door. I tested the obvious one — Leboncoin's internal mobile API (api.leboncoin.fr/finder/search), the JSON endpoint the app uses. From a residential IP, with and without an app key:
HTTP 403 → {"url":"https://geo.captcha-delivery.com/captcha/?..."}
DataDome sits in front of the web pages and the internal API. A plain residential IP + stealth browser passes lighter anti-bot (Google Maps, Amazon, Pages Jaunes) but not DataDome's hard mode. Don't waste a week on undetected-chromedriver here.
What actually works: solver-backed residential unlocker
The only reliable path is a service that (a) provides a residential IP and (b) solves the DataDome challenge. I routed the request through one, asking for a French residential proxy + JS render + antibot, and got a clean 200 with the full page:
HTTP 200 | 1.05 MB | not blocked | __NEXT_DATA__ present
The honest tradeoff: it's not free. A premium+antibot+JS-render request burns real credits (~$0.005–0.02 each). If someone tells you DataDome is beatable for free at scale, they're selling you a cookie that expires in a few hours.
Don't parse the DOM — read the embedded JSON
Once you're through, both sites hand you structured data if you know where to look:
-
Leboncoin is a Next.js app: the ads are in
__NEXT_DATA__atprops.pageProps.searchData.ads— each withlist_id,subject,price,location,owner.type(private/pro),images,attributes. No brittle CSS selectors.
const m = html.match(/<script id="__NEXT_DATA__"[^>]*>([\s\S]*?)<\/script>/);
const ads = JSON.parse(m[1]).props.pageProps.searchData.ads;
-
SeLoger renders cards you can read with
data-testid(sl.explore.card-container,sl.explore-card-price). One gotcha that cost me a 422: SeLoger'sinseeCodesparam zero-pads the commune to 4 digits — INSEE33063(Bordeaux) becomes330063. Miss that and you get "could not get content".
The result
Clean, structured listings from both:
Leboncoin "iphone" Bordeaux → 3976 results
60 € | iPhone 11 | private | 2026-07-23
130 € | iPhone 11 - Garantie | pro
SeLoger Bordeaux → median 5657 €/m²
Appartement 4p 163m² | 1 370 000 € | 8422 €/m²
I wrapped both as pay-per-result actors so you don't have to manage the unlocker, cookies or the SeLoger code quirk:
- Leboncoin: https://apify.com/x402farm/leboncoin-scraper
- SeLoger: https://apify.com/x402farm/seloger-scraper
- The wider farm (residential scraping + French business data): https://api.x-402.online/start
Happy to answer questions on the DataDome specifics in the comments.
Top comments (0)