Doctolib.fr Scraper
Pricing
from $6.97 / 1,000 results
Doctolib.fr Scraper
Scrape practitioner and practice profiles from Doctolib.fr: name, speciality, address, geo-coordinates, departement, billing sector, languages, online booking and next-availability. No phone, email or personal contact data. GDPR-first with robots.txt checks and a suppression list.
Pricing
from $6.97 / 1,000 results
Rating
0.0
(0)
Developer
Unfenced Group
Maintained by CommunityActor stats
1
Bookmarked
6
Total users
2
Monthly active users
8 days ago
Last modified
Categories
Share

Extract practitioner and practice profiles from Doctolib.fr at scale: name, speciality, practice address with geo-coordinates, billing sector, spoken languages, online-booking status and next-appointment availability. Clean, structured JSON ready for healthcare market mapping and directory building. No API key required. No personal contact data is collected.
Why this scraper?
🎯 Built for Doctolib.fr
A dedicated French scraper tuned for Doctolib's data model, speciality slugs, billing sectors and currency (EUR) — not a generic tool pointed at the site.
🩺 Complete professional profile
Full name, speciality, profile type (individual practitioner vs practice), practice organisation type, and profile photo — everything the public directory exposes.
📍 Precise location and mapping
Street address, ZIP code, derived French département, city, latitude/longitude and a ready-to-use Google Maps link for every record.
💶 Structured billing data
French convention status (conventionné), billing sector (1/2/3) and accepted payment methods, parsed into clean fields.
📅 Booking and availability signals
Online-booking status, whether the practitioner accepts new patients, and — on request — the next available appointment and open-slot count.
🔒 GDPR-first, no contact PII
No phone numbers, no email addresses, no individual contact data. Only manifestly-public professional directory information, with a built-in suppression list to honour erasure and objection requests.
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
specialities | array | ["medecin-generaliste"] | Speciality slugs as used in Doctolib URLs (e.g. dentiste, dermatologue, cardiologue, pediatre, psychiatre, ophtalmologue). |
cities | array | ["paris"] | City slugs (lowercase, hyphenated). Precise geo-anchoring for: paris, lyon, marseille, toulouse, bordeaux, lille, nantes, strasbourg, montpellier, nice, rennes, grenoble. |
maxResultsPerQuery | integer | 5 | Maximum practitioners to return per speciality + city pair. |
scrapeDetailPages | boolean | false | Fetch each profile for biography, opening hours and procedures. Adds a few seconds per record. |
scrapeAvailability | boolean | false | Query the availability API for the next open slot and slot count. |
onlyAcceptingNewPatients | boolean | false | Keep only practitioners open to new patients. |
languageFilter | array | [] | Keep only practitioners speaking at least one of these languages (Doctolib codes, e.g. fr, gb, ar, es). Empty means no filter. |
suppressedDoctorIds | array | [] | Doctor IDs to skip (GDPR erasure / objection). |
suppressedDoctorSlugs | array | [] | Profile slugs to skip (GDPR erasure / objection). |
skipRobotsCheck | boolean | false | Bypass the robots.txt compliance check. Local testing only. |
proxyConfiguration | object | Apify RESIDENTIAL | Proxy settings. French residential proxies recommended. |
maxConcurrency | integer | 5 | Parallel requests. |
requestDelay | integer | 500 | Delay between requests, in milliseconds. |
Output schema
Every field below is present on every record. Fields the source does not publish for a given practitioner are returned as null (or an empty array) rather than omitted.
Always present (search stage)
| Field | Type | Description |
|---|---|---|
doctorId | number | Doctolib internal profile ID. |
profileSlug | string | Profile slug. |
profileUrl | string | Direct link to the Doctolib profile. |
fullName | string | Practitioner or practice name, including title. |
firstName | string | null | First name. Null for practices. |
lastName | string | Last name, or practice name. |
gender | string | null | F or M. Null when the source does not publish it (~55% present). |
profilePhoto | string | Profile photo URL. |
speciality | string | Speciality slug. |
specialityName | string | Human-readable speciality. |
specialities | array | Speciality slugs. |
type | string | doctor or practice. |
isPractice | boolean | True for practices/clinics. |
organizationType | string | null | Practice category (e.g. Centre de santé, Hôpital public, Cabinet médical). Null for individual practitioners. |
city | string | City. |
zipCode | string | Postal code. |
departement | string | French department code, derived from the postal code. |
address | string | Full formatted address. |
addressStreet | string | Street line only. |
latitude | number | Latitude. |
longitude | number | Longitude. |
distanceMeters | number | Distance from the city search anchor, in metres. |
googleMapsUrl | string | Google Maps link built from the coordinates. |
hasOnlineBooking | boolean | True when online booking is available. |
acceptsNewPatients | boolean | null | Whether the matched appointment type accepts new patients. |
agendaIds | array | Doctolib agenda IDs. |
practiceIds | array | Doctolib practice IDs. |
visitMotives | array | Matched appointment type(s): id, name, agendaIds, allowNewPatients. |
hasTelehealth | boolean | True when teleconsultation is offered. |
isConventionne | boolean | True when the standard French insurance tariff is accepted. |
sector | string | null | Billing sector: 1, 2 or 3 (~55% present). |
paymentMethods | array | Accepted payment methods (e.g. cash, check, credit_card). |
languages | array | Languages spoken (Doctolib codes; ~85% present). |
dataSource | string | Stages that contributed: search, detail, availability. |
_compliance | object | GDPR metadata: legal basis, retention guidance, DSR contact, timestamp. |
With scrapeDetailPages: true
| Field | Type | Description |
|---|---|---|
biography | string | null | Practitioner/practice biography from the profile page. Best-effort (~50% of profiles). |
openingHours | array | null | Weekly opening hours in schema.org format. Best-effort (~50%). |
procedures | array | Treatments/procedures. Individual practitioners only (practices rarely publish them). |
With scrapeAvailability: true
| Field | Type | Description |
|---|---|---|
nextAvailableDate | string | null | Next open appointment (ISO). Often null — most agendas have no slot in the sampled window. |
totalAvailableSlots | number | Number of open slots found in the sampled window. |
Example record
{"doctorId": 8356,"profileSlug": "axelle-mon-wen-pin","profileUrl": "https://www.doctolib.fr/medecin-generaliste/paris/axelle-mon-wen-pin","fullName": "Dr Axelle MON WEN PIN","firstName": "Axelle","lastName": "MON WEN PIN","gender": "F","profilePhoto": "https://media.doctolib.com/image/upload/q_auto:eco,f_auto,dpr_2/w_80,h_80,c_fill,g_face/qtk0bdltbffmvkbdkpsr.jpg","speciality": "medecin-generaliste","specialityName": "Médecin généraliste","specialities": ["medecin-generaliste"],"type": "doctor","isPractice": false,"organizationType": null,"city": "Paris","zipCode": "75001","departement": "75","address": "58 Rue Jean-Jacques Rousseau, 75001 Paris","addressStreet": "58 Rue Jean-Jacques Rousseau","latitude": 48.8639767,"longitude": 2.3435852,"distanceMeters": 914.29,"googleMapsUrl": "https://www.google.com/maps/search/?api=1&query=48.8639767,2.3435852","hasOnlineBooking": true,"acceptsNewPatients": true,"agendaIds": [1149767, 11115],"practiceIds": [807199],"visitMotives": [{ "id": 7785341, "name": "Consultation (médecine esthétique)", "agendaIds": [11115, 1149767], "allowNewPatients": true }],"hasTelehealth": true,"isConventionne": true,"sector": "1","paymentMethods": ["cash", "check", "credit_card"],"languages": ["fr", "gb"],"biography": "Le docteur Axelle MON WEN PIN vous accueille dans son cabinet à Paris. […]","procedures": ["Médecine esthétique", "Vaccination"],"openingHours": ["Mo 09:00-13:00, 14:00-19:00", "Tu 17:15-20:15", "We 09:00-13:00"],"nextAvailableDate": null,"totalAvailableSlots": 0,"dataSource": "search+detail+availability","_compliance": {"legalBasis": "Legitimate Interest (GDPR Art. 6(1)(f))","piiNote": "No phone, email or other individual contact data is collected.","retentionRecommendation": "Delete or re-scrape after 90 days (Art. 5(1)(d) accuracy principle)","scrapedAt": "2026-07-10T08:19:00.000Z"}}
Examples
All general practitioners in Paris:
{"specialities": ["medecin-generaliste"],"cities": ["paris"],"maxResultsPerQuery": 50}
Dentists in Lyon accepting new patients who speak English:
{"specialities": ["dentiste"],"cities": ["lyon"],"onlyAcceptingNewPatients": true,"languageFilter": ["gb"],"maxResultsPerQuery": 50}
Full profile detail plus next availability:
{"specialities": ["dermatologue"],"cities": ["bordeaux"],"scrapeDetailPages": true,"scrapeAvailability": true,"maxResultsPerQuery": 25}
Multi-speciality, multi-city sweep:
{"specialities": ["pediatre", "gynecologue", "ophtalmologue"],"cities": ["paris", "lyon", "marseille"],"maxResultsPerQuery": 100}
💰 Pricing
$7.00 per 1,000 results — you only pay for successfully retrieved practitioners. Failed retries are never charged.
| Results | Cost |
|---|---|
| 100 | ~$0.70 |
| 1,000 | ~$7.00 |
| 10,000 | ~$70.00 |
| 100,000 | ~$700.00 |
Flat-rate alternatives typically charge $29–$49/month regardless of usage.
Subscription tiers lower the rate to $6.95 per 1,000 at the highest tier. Use the Max results per query cap to control your spend exactly.
Performance
| Run size | Typical time |
|---|---|
| 100 results (search only) | 1–2 minutes |
| 1,000 results (search only) | 4–8 minutes |
| 1,000 results with detail pages | 15–30 minutes |
Detail pages and availability add per-record requests, so runs with scrapeDetailPages or scrapeAvailability enabled take longer.
Known limitations
- No contact data by design. Phone numbers and email addresses are deliberately not collected. This is a GDPR/PII compliance choice, not a source limitation.
- Detail fields are best-effort.
biographyandopeningHourscome from the profile page and fill on roughly half of profiles; the rest do not publish them or return a challenge page. - Procedures are practitioner-level.
proceduresare published by individual practitioners; practices and clinics rarely expose them. - Availability is sparse.
nextAvailableDateis often null — most agendas have no open slot in the short sampled window. - City geo-anchoring. Cities outside the built-in coordinate list are anchored to Paris; use a listed city for precise geo-targeting.
Technical details
- Source: Doctolib.fr — French healthcare practitioner and practice directory.
- Coverage: everything the public search and profile pages expose, filterable via the input parameters above.
- Compliance: robots.txt checked on every run; built-in GDPR suppression list; legitimate-interest legal basis documented per record.
- Retry: automatic retry on network errors with backoff and fresh proxy rotation.
Need a custom scraper?
Unfenced Group builds Apify actors for any website — for free.
If the site you need isn't in our portfolio yet, just ask. We scope, build, and publish it at no cost to you. You only pay for results — we absorb the compute and proxy costs ourselves. Same pay-per-result pricing, same quality, same standards as every actor in this portfolio.
Get in touch: www.unfencedgroup.nl