leboncoin Scraper — search French classified ads
Pricing
$3.00 / 1,000 ad scrapeds
leboncoin Scraper — search French classified ads
Scrape leboncoin.fr search results past DataDome: title, price, location, seller, images and every ad attribute, about 35 ads per page. No browser. Powered by xhr.dev.
Pricing
$3.00 / 1,000 ad scrapeds
Rating
0.0
(0)
Developer
xhrdev
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
3 days ago
Last modified
Categories
Share
Scrape leboncoin.fr search results past DataDome. Give it a keyword or a filtered search URL and it returns roughly 35 ads per page — title, price, full description, precise location with coordinates, seller name and professional/private status, every image, and the whole attribute block the site keeps per category (surface area and room count for property, mileage and fuel for cars, size and brand for clothing).
No browser is launched. The DataDome challenge is solved as plain HTTP by xhr.dev, which is why a page takes a few seconds and a few hundred milliseconds of compute rather than the several seconds and gigabyte of RAM a stealth-browser scraper needs.
Quickstart
Paste this into the input and press Run.
{"queries": ["vélo"],"maxPagesPerQuery": 1}
What this Actor does not do
Ad detail pages are not supported. leboncoin puts a second layer of protection on individual /ad/ pages that this Actor does not get past — they return 403 even after the challenge has cleared. Passing one is rejected at the start of the run with an explanation, rather than being fetched and quietly returning nothing.
This matters less than it sounds: the search results carry the full ad body and the complete attribute block, so for most purposes the listing page already contains what a detail page would tell you.
Input
| Field | Type | Default | Description |
|---|---|---|---|
queries | string[] | ["vélo"] | Keywords to search. Each runs as its own search, exactly as typing it into the site's search box. |
startUrls | array | [] | leboncoin search URLs, for when you want the site's own filters — category, region, price band. Filter in your browser and copy the URL. Ad detail pages are not accepted (see below). |
maxPagesPerQuery | integer | 1 | How deep to page each search, 1–100. Roughly 35 ads per page. |
maxItems | integer | 200 | Stop once this many ads have been scraped across the whole run. |
proxyConfiguration | object | Apify RESIDENTIAL | Which proxy to route through. Leave it on residential — see Proxies. |
maxRetries | integer | 3 | Attempts per page before giving up on it, 1–5. Each attempt takes a fresh proxy session. |
timeoutSecs | integer | 120 | How long one page — challenge, solve and all — may take before the attempt fails. 10–300. |
maxConcurrency | integer | 4 | Pages worked on at once, 1–10. |
Nothing is required — the defaults run a real search out of the box.
Output
One dataset item per ad. Fields absent from an ad are omitted rather than returned as null, so rows stay clean across categories.
| Field | Type | Description |
|---|---|---|
id | number | leboncoin ad ID. |
title | string | Ad title. |
description | string | Full ad body text. |
price | number | Price in euros. |
currency | string | Always EUR. |
url | string | Canonical ad URL. |
category | string | Category name, e.g. Ventes immobilières. |
brand | string | Listing brand where the site records one. |
publishedAt | string | First publication timestamp. |
city / zipcode | string | Town and postcode. |
department / region | string | French département and région names. |
latitude / longitude | number | Coordinates, precise enough to map directly. |
sellerName | string | Seller or shop name. |
sellerType | string | pro or private. |
imageCount | number | Number of photos on the ad. |
images | string[] | Full-size image URLs. |
thumbnail | string | Thumbnail URL. |
attributes | object | Everything else the ad carries, as key/value pairs. Category-dependent — property ads bring Surface habitable and Nombre de pièces, vehicles bring mileage and fuel. This is where most of the value is. |
Example record
Taken verbatim from a live run. Long text and image lists are trimmed here for readability; the real record carries them in full.
{"id": 2327033825,"title": "Appartement - 4 pièces - AART","price": 365000,"currency": "EUR","url": "https://www.leboncoin.fr/ad/ventes_immobilieres/2327033825","category": "Ventes immobilières","brand": "leboncoin","publishedAt": "2023-04-01 07:20:35","city": "Strasbourg","zipcode": "67000","department": "Bas-Rhin","region": "Alsace","latitude": 48.60022,"longitude": 7.76147,"sellerName": "SAS LPA ARCHIPEL 2","sellerType": "pro","imageCount": 1,"images": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/38/18/95/381895809b2436561935339711b556d622762a0c.jpg?rule=ad-image"],"thumbnail": "https://img.leboncoin.fr/api/v1/lbcpb1/images/38/18/95/381895809b2436561935339711b556d622762a0c.jpg?rule=ad-thumb","attributes": {"activity_sector": "2","external_ad_id": "lbcin_P200798","has_variation": "true","Type de bien": "Appartement","Surface habitable": "75 m²","Nombre de pièces": "4","Honoraires inclus": "Non","district_id": "3001188","district_visibility": "false","district_type_id": "9","…": "17 more attributes"}}
Pricing
$3.00 per 1,000 ads (listing-item, $0.003 each), charged only on ads actually delivered to your dataset. Pages that fail are not charged.
A 1,000-ad run is about $3.00, plus Apify platform costs — mostly residential proxy traffic, which is the real variable. Budget roughly $0.50–1.50 per 1,000 ads of proxy on top.
Proxies: read this before changing anything
Set this to Apify RESIDENTIAL and leave it there. It is not a style preference, and it is the single most common reason a run comes back empty.
DataDome decides which challenge to serve based on the exit IP. We measured this from Apify against twelve DataDome-protected sites, same code, minutes apart:
| Exit IP | Challenge served | Result |
|---|---|---|
| Datacenter (Apify default, or no proxy) | The hard captcha | 3 of 12 sites passed |
| Residential | Interstitial, or no challenge at all | 12 of 12 sites passed, 2–5s each |
A datacenter address does not make leboncoin slower. It changes the problem into a different, much harder one. Every attempt already pins a fresh residential session automatically, so a burnt exit node gets a genuinely new IP rather than a retry down the same dead pipe.
If a run fails wholesale, check the proxy group before anything else.
Run it from the API or CLI
Replace <TOKEN> with your Apify API token.
Run and get the results back in one call:
curl -X POST "https://api.apify.com/v2/acts/xhrdev~leboncoin-scraper/run-sync-get-dataset-items?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"queries":["vélo"],"maxPagesPerQuery":1}'
Start a run without waiting:
curl -X POST "https://api.apify.com/v2/acts/xhrdev~leboncoin-scraper/runs?token=<TOKEN>" \-H "Content-Type: application/json" \-d '{"queries":["vélo"],"maxPagesPerQuery":1}'
With the Apify CLI:
$apify call xhrdev/leboncoin-scraper --input '{"queries":["vélo"],"maxPagesPerQuery":1}'
Fetching results
Every run writes to a dataset. Change format for JSON, CSV, or Excel:
# JSONcurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=json"# CSVcurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&clean=true&format=csv"# Page through a large datasetcurl "https://api.apify.com/v2/datasets/<DATASET_ID>/items?token=<TOKEN>&offset=1000&limit=1000"
<DATASET_ID> comes back as defaultDatasetId on the run object.
Limits and failure behaviour
100 pages per run, hard. Not configurable. It is a guard against a typo in maxPagesPerQuery turning into a bill and a hammering of leboncoin. For more than that, split the work across runs.
Failures never enter the dataset. A page that could not be fetched is not written as a half-empty row — that would corrupt the clean table you are paying for. Instead every run writes a RUN_SUMMARY record to the key-value store:
{"site": "leboncoin","itemsScraped": 35,"pagesFetched": 1,"pagesFailed": 0,"failures": [],"solverHost": "https://trial.xhr.dev"}
Read it at https://api.apify.com/v2/key-value-stores/<STORE_ID>/records/RUN_SUMMARY. failures holds up to 50 entries, each with the URL and why it failed.
A run that scrapes nothing and failed at least one page exits as failed, rather than reporting success over an empty dataset. If everything failed, the message points at the proxy group first, because that is nearly always the cause.
Pagination is never speculative. Page 2 is queued only after page 1 comes back and the site confirms how many pages exist, so you are not billed for fetching past the end of a short result set.
Spend cap. Set maxTotalChargeUsd on the run. The Actor stops fetching once it is reached, mid-run, rather than overshooting.
Questions
A run came back empty. Why?
Check the proxy group first — a datacenter exit is the cause the overwhelming majority of the time. Then read RUN_SUMMARY in the key-value store for the per-page reasons.
Is this affiliated with leboncoin? No. This is an independent tool with no affiliation with, endorsement by, or connection to leboncoin or any bot-protection vendor. Names and trademarks belong to their owners.
How does it get past the challenge without a browser? It is solved as HTTP, by xhr.dev. No Chrome is launched, which is why a page costs a few hundred milliseconds of compute instead of the several seconds and ~1 GB of RAM a stealth browser needs.
Can I use the solver directly, on a site that isn't leboncoin? Yes — that is DataDome Unblocker, which takes any URL and hands back the HTML and the clearance cookies. There is also Akamai Unblocker for Akamai Bot Manager.
Can I run this on my own infrastructure? Yes. The solver these Actors call is a self-hosted Docker container, sold on a flat fee with no per-request pricing. See xhr.dev.
Why does attributes have different keys for different ads?
Because leboncoin genuinely stores different fields per category. It is passed through as-is rather than flattened into a fixed schema, so nothing is lost. Use unwind or flatten on the dataset API if you need columns.
Related Actors
- DataDome Unblocker — any URL behind DataDome, returns HTML plus clearance cookies.
- Akamai Unblocker — the same, for Akamai Bot Manager.
- Etsy Scraper — handmade marketplace listings.
- Anthropologie Scraper — apparel and homeware.
- Grainger Scraper — industrial supply lookups.
Built by xhr.dev. Independent tool, not affiliated with leboncoin or any bot-protection vendor. Scrape only what you are permitted to access, and check the site's terms before you run anything at scale.