Bookimed.com Medical Tourism Scraper
Pricing
from $3.00 / 1,000 results
Bookimed.com Medical Tourism Scraper
Bookimed scraper & API: find clinics and hospitals for medical treatments and export clinic name, country, treatments, prices, rating and reviews, accreditation and profile. Medical-tourism market data and healthcare lead generation — fast, no login.
Pricing
from $3.00 / 1,000 results
Rating
0.0
(0)
Developer
Haketa
Maintained by CommunityActor stats
0
Bookmarked
7
Total users
3
Monthly active users
6 days ago
Last modified
Categories
Security
Limited permissionsShare
Bookimed Scraper — Medical Tourism Clinic, Price, Doctor & Review Data Extractor
The most complete Bookimed.com scraper on Apify. This Bookimed scraper pulls structured records for medical tourism clinics and hospitals — clinic name, country, city, treatment prices, ratings, review counts, certifications, featured doctors, and (on profile pages) full patient reviews, doctor rosters, success rates and contact details — across 45 destination countries and 13 languages. No login, no coding, no CSS-selector maintenance.
Export every result to JSON, CSV, Excel, or API.
Built for medical tourism agencies and patient coordinators, price-comparison and benchmarking teams, insurers and self-funded health plans, health-content and affiliate publishers, market-research and PE/VC analysts, medical-device and pharma sales teams, and academic/public-health researchers who need clean, structured Bookimed data without manual copy-paste.
🔎 Why scrape Bookimed?
Bookimed.com is the world's largest medical tourism marketplace — a single destination where international patients compare 1,600+ accredited clinics and hospitals across 50+ countries for procedures like hair transplant, dental implants, rhinoplasty, IVF, cosmetic surgery, oncology, cardiac surgery, bariatric surgery and organ transplant. Each listing bundles a price teaser, a verified-review rating, accreditation badges, a featured surgeon and a deep profile page with the full treatment menu.
That richness is exactly what makes scraping Bookimed by hand so painful. Results are paginated behind a JavaScript "Load More" button that reveals only a handful of clinics at a time, prices are buried in marketing copy, and the data is hydrated client-side from a Nuxt 3 single-page app rather than served as clean HTML. Collecting a few hundred clinics manually — with prices, ratings and certifications attached — is hours of tedious clicking and copy-paste that goes stale the moment a clinic updates a price.
This Bookimed scraper automates the whole pipeline: it opens the listing in a real browser, clicks "Load More" until the listing is exhausted, parses every clinic card into a flat JSON record, normalizes prices and certifications, de-duplicates across overlapping searches, and (optionally) opens each clinic profile to enrich it with patient reviews, doctor rosters, success rates and contact details.
Common reasons people scrape Bookimed:
- Build clinic shortlists by country, city and procedure for inbound medical-tourism patients
- Benchmark procedure prices (hair transplant, dental, IVF, bariatric, cosmetic) across Turkey, India, Thailand, Mexico, Hungary and more
- Generate lead lists of clinics and hospitals for medical-device, pharma and B2B outreach
- Power price-comparison dashboards and "how much does X cost in Y country" content pages
- Monitor ratings, review counts and certifications over time to flag quality changes
- Mine patient-review text for sentiment, complaint themes and doctor-reputation signals (profile mode)
- Feed CRMs and warehouses with a refreshed clinic + price feed on a schedule
✨ What this Bookimed scraper does
- ✅ Two targeting modes — pick countries + cities + procedures from dropdowns, or paste direct Bookimed listing / clinic-profile URLs in
startUrlsfor anything outside the dropdowns (IVF, gastric sleeve, LASIK, etc.). - ✅ Automatic "Load More" pagination — clicks the listing's "Load More" button up to
maxLoadMoretimes (each click reveals ~5 more clinics), returning hundreds of de-duplicated clinic records per run. - ✅ Real captured fields on every listing record —
clinicName,clinicUrl,country,city,treatmentPrices(itemized{treatment, min, max, currency}),certifications(JCI / ISO / TEMOS / NABH / ISQua), plusreviewCountandratingwhere published on the card, and full search-context provenance (searchCountry,searchCity,searchProcedure,scrapedAt). - ✅ Deep profile enrichment (optional) — set
scrapeDetails: trueto open each clinic profile and additionally capture individual patientreviews(author, rating, full text, date, treatment, country, doctor),ratingBreakdown(5★ distribution),doctorsroster,successRates,description,accreditations,address,phone,email,foundedYear,beds,languages,specialties,patientOrigins,patientsPerYearandphotos— straight from the page's hydrated Nuxt state and JSON-LD, with regex/DOM fallbacks. - ✅ Multi-currency price parsing — USD and EUR teasers are normalized into structured
{ treatment, min, max, currency }objects;maxisnullfor single-figure ("from $X") prices. - ✅ 13 languages / regional subdomains —
us-uk,de,ru,es,fr,it,pt,ar,ja,tr,pl,ro,hu; the actor routes through the correct{lang}.bookimed.comsubdomain. - ✅ De-duplication — a
Setkeyed onclinicUrlguarantees each clinic is saved exactly once, even when it matches several overlapping searches. - ✅ Resilient & polite — headless Chromium via Playwright, image/font/webfont blocking to cut bandwidth, retry-with-backoff on 403/429/503, configurable
requestDelay, and Apify Proxy enabled by default. - ✅ Export anywhere — JSON, CSV, Excel (XLSX), HTML, XML, JSON Lines, or the Apify dataset API.
🎯 Use cases
- Medical tourism agencies & patient coordinators — build a clinic shortlist per inbound patient, quote min/max prices across competing facilities instantly, and refresh your CRM so quotes never drift from the live Bookimed listing.
- Price comparison & procedure benchmarking — compare hair-transplant, dental, IVF and bariatric prices across Istanbul, Tijuana, Budapest and Bangkok side-by-side; build a monthly median-cost-per-country index.
- Insurance & self-funded health plans — estimate out-of-network and cross-border referral costs, benchmark US prices vs. JCI-accredited overseas alternatives, and archive timestamped scrapes for due diligence.
- Content, SEO & affiliate sites — power "Top 10 clinics in {city}" lists and "how much does {procedure} cost in {country}" landing pages with verified ratings, review counts and current price ranges.
- Market research & industry intelligence — map clinic density per metro and specialty, track new clinic openings by diffing weekly runs, and quantify "Big 5" destination market share.
- Medical-device & pharma sales — source qualified clinic/hospital accounts by country, specialty and patient volume for outbound campaigns and Salesforce/HubSpot enrichment.
- IVF, fertility & reproductive tourism — discover clinics by destination and (profile mode) success rate, compare egg-donation markets, and build country-comparison decks.
- Journalism & academic research — investigate price disparities, model price elasticity across procedure categories, and study accreditation and patient-flow patterns using
patientOrigins.
📥 Input
Pick destinations, cities and procedures from the dropdowns, or paste direct URLs. Just click Start with the defaults to get a ready sample.
| Parameter | Type | Default | Description |
|---|---|---|---|
countries | array<string> | [] (prefill ["turkey"]) | Destination country picker (fixed dropdown of 45 slugs: turkey, india, thailand, mexico, germany, spain, republic-of-korea, united-arab-emirates, czech-republic, poland, hungary, israel, …). Empty = a ready mixed sample of popular destinations. |
cities | array<string> | [] | City picker (fixed dropdown) to narrow each country: istanbul, antalya, izmir, ankara, bangkok, phuket, mumbai, delhi, chennai, berlin, munich, barcelona, madrid, cancun, tijuana, budapest, prague, warsaw. Empty = whole country. |
citiesCustom | array<string> | [] | Free-text city names not in the dropdown (e.g. adana, goa). Combined with cities. |
procedures | array<string> | [] | Procedure picker (15 slugs incl. hair-transplant, dental-implant, rhinoplasty-nose-job, breast-augmentation, liposuction, knee-replacement, coronary-artery-bypass-grafting, kidney-transplant, treatment-with-stem-cells). Empty = all procedures. Need IVF/gastric-sleeve/LASIK? Use startUrls. |
language | string | us-uk | Site language / regional subdomain. One of us-uk, de, ru, es, fr, it, pt, ar, ja, tr, pl, ro, hu. |
startUrls | array<object> | [] | Direct Bookimed listing or clinic-profile URLs, scraped in addition to the selections above. Accepts any country=/city=/procedure= slug — the escape hatch for anything outside the dropdowns. Format: [{ "url": "https://..." }]. |
scrapeDetails | boolean | false | When true, opens every clinic profile for the full description, all doctors, patient reviews, success rates, patient origins and complete treatment list. Slower, much richer. |
maxClinics | integer | 0 | Total clinic cap across all searches. 0 = unlimited (Console prefills 100 for a quick first run). |
maxLoadMore | integer | 10 | Max "Load More" clicks per listing (each ≈5 more clinics). 0 = click until the button disappears. |
requestDelay | integer | 1500 | Milliseconds between detail-page requests. Raise if you trip 429s. |
proxyConfiguration | object | { useApifyProxy: true } | Standard Apify proxy block. The default (datacenter) works out of the box; switch to residential if you scrape the tr./ru. subdomains heavily. |
Example input
{"countries": ["turkey", "india", "thailand", "mexico"],"cities": [],"procedures": [],"language": "us-uk","scrapeDetails": false,"maxClinics": 500,"maxLoadMore": 25,"proxyConfiguration": { "useApifyProxy": true },"requestDelay": 1000}
📤 Output
Every record is a flat JSON object — one row per clinic, ready for CSV/Excel or ingestion into Postgres/BigQuery/Snowflake. The example below is a real listing-mode record from the latest verification run (scrapeDetails: false):
{"clinicName": "Lokman Hekim Istanbul","clinicUrl": "https://us-uk.bookimed.com/clinic/lokman-hekim-istanbul/","country": "Turkey","city": "Istanbul","rating": null,"reviewCount": 296,"certifications": ["JCI", "ISO 9001"],"treatmentPrices": [{ "treatment": "Blood test for hormonal profile", "min": 219, "max": 328, "currency": "USD" },{ "treatment": "Consultation with a neurosurgeon", "min": 112, "max": null, "currency": "USD" },{ "treatment": "Knee Arthroscopy", "min": 1820,"max": 2870, "currency": "USD" },{ "treatment": "Breast lift", "min": 2440,"max": 2700, "currency": "USD" }],"patientsPerYear": null,"specialties": null,"featuredDoctor": null,"description": null,"successRates": null,"patientOrigins": null,"doctors": null,"address": null,"photos": null,"verified": null,"searchCountry": "turkey","searchCity": null,"searchProcedure": null,"scrapedAt": "2026-11-02T00:24:17.306Z"}
When you run with scrapeDetails: true, the same record is enriched with profile-only fields — a trimmed real-shape example:
{"clinicName": "Memorial Şişli Hospital","clinicUrl": "https://us-uk.bookimed.com/clinic/memorial-sisli-hospital/","country": "Turkey","city": "Istanbul","rating": 4.8,"reviewCount": 520,"certifications": ["JCI", "ISO 9001"],"accreditations": ["JCI"],"specialties": ["Oncology", "Cardiology", "Orthopedics"],"treatmentPrices": [{ "treatment": "Bone marrow transplant", "min": 45000, "max": 60000, "currency": "USD" }],"doctors": [{ "name": "Prof. Dr. Example Surgeon", "specialization": "Oncology", "qualifications": "30 years", "photo": null, "rating": null, "reviewCount": null }],"reviews": [{ "author": "Maria K.", "rating": 5, "text": "The oncology team explained every step in clear English…", "date": "2025-11-14", "treatment": "Breast cancer treatment", "country": "Romania", "doctor": null }],"ratingBreakdown": { "5": 420, "4": 60, "3": 20, "2": 10, "1": 10 },"description": "Memorial Şişli Hospital is a JCI-accredited multi-specialty hospital in Istanbul…","patientOrigins": ["Germany", "United Kingdom", "Saudi Arabia"],"address": "Şişli, Istanbul","phone": "+90 …","email": null,"foundedYear": 2000,"beds": 200,"languages": ["English", "Russian", "Arabic"],"searchCountry": "turkey","searchCity": "istanbul","searchProcedure": null,"scrapedAt": "2026-11-02T00:25:00.000Z"}
Field reference
| Field | Type | Description |
|---|---|---|
clinicName | string | Clinic display name. Falls back to the title-cased URL slug. Always present. |
clinicUrl | string | Canonical Bookimed profile URL on the selected language subdomain. Always present and used as the de-duplication key. |
country | string | Country name (from the search slug or JSON-LD). Always present. |
city | string | City name from the search slug, card text, or JSON-LD. Present on most records. |
treatmentPrices | array<object> | Itemized pricing: { treatment, min, max, currency }. currency is USD or EUR; max is null for single-figure prices. Present when the clinic publishes a price teaser. |
certifications | array<string> | Accreditations detected on the card: JCI, ISO 9001, TEMOS, NABH, ISQua, Gold Seal. Present when badged. |
rating | number | Aggregate Bookimed rating (0–5). Present when exposed on the card; populated far more often in scrapeDetails: true mode. |
reviewCount | integer | Verified patient-review count. Present on many cards; always available in profile mode. |
searchCountry / searchCity / searchProcedure | string | The exact slug(s) that produced this record — provenance for auditing and joins. |
scrapedAt | string | ISO-8601 extraction timestamp. Always present. |
reviews | array<object> | Individual patient reviews { author, rating, text, date, treatment, country, doctor }. Profile mode only. |
ratingBreakdown | object | 5★ distribution { "5": n, …, "1": n }. Profile mode only. |
doctors | array<object> | Doctor roster { name, specialization, qualifications, photo, rating, reviewCount }. Profile mode only. |
specialties | array<string> | Medical specialties / departments. Profile mode only. |
successRates | object | Procedure → success-percentage map. Profile mode only (as published by the clinic). |
description | string | Long-form clinic description. Profile mode only. |
accreditations | array<string> | Accreditation list from the hydrated state (complements certifications). Profile mode only. |
address / phone / email | string | Contact details when published. Profile mode only. |
foundedYear / beds | integer | Facility metadata when published. Profile mode only. |
languages | array<string> | Languages spoken by staff. Profile mode only. |
patientOrigins | array<string> | Countries patients travel from. Profile mode only. |
patientsPerYear | integer | Annual international-patient volume when published. Profile mode only. |
photos | array<string> | Up to 10 gallery image URLs (logos/icons/flags excluded). Profile mode only. |
featuredDoctor | object | { name, yearsExperience } for a card's lead surgeon. Best-effort — populated only when the current card markup exposes it cleanly. |
verified | boolean | Bookimed verification flag when published. |
Honest coverage note. In high-volume listing mode (scrapeDetails: false), the identity fields — clinicName, clinicUrl, country, searchCountry, scrapedAt — populate at 100%, city at ~78%, treatmentPrices at ~62% and certifications at ~31% (data-dependent on what each clinic publishes). rating, reviewCount, featuredDoctor and all profile-only fields are best-effort on the card and are intended to be filled by running with scrapeDetails: true, which opens each profile and reliably unlocks reviews, ratingBreakdown, doctors, description, specialties, accreditations and contact fields. Fields marked "profile mode only" are null in listing mode by design — that is expected, not a defect.
🔁 Pagination & scale
Bookimed listings are paginated behind a JavaScript "Load More" button — the initial page renders only a handful of clinics and each click appends ~5 more. The actor drives this automatically:
- It clicks "Load More" (in your chosen language) up to
maxLoadMoretimes per listing page, waiting for new content between clicks. - It parses the fully-expanded listing, then de-duplicates against a
Setof everyclinicUrlalready saved. maxClinicscaps the total across all country/city/procedure searches (0= unlimited).- Multiple
countries,citiesandproceduresfan out into sequential searches so overlapping results are collected once and only once.
In practice this returns hundreds of unique clinics per run — the latest verification pulled 500 unique, zero-duplicate clinic records across Turkey, India and Thailand in about 5.5 minutes. Set maxClinics: 0 and maxLoadMore: 0 for exhaustive collection (expect 100–400+ clinics per major country), or keep a cap for fast sampling.
⚙️ How to use
- On Apify Console: open the actor, pick one or more countries (optionally narrow with cities / procedures), set
maxClinicsandmaxLoadMore, and click Start. Records stream into your dataset in real time. - Via API:
POST https://api.apify.com/v2/acts/haketa~bookimed-scraper/runs?token=YOUR_TOKENwith the JSON input above. - On a schedule: use Apify's built-in Scheduler (cron) for a nightly/weekly refresh.
- Choose your export: download the dataset as JSON, CSV, Excel, HTML, XML or JSON Lines, or pull it from the dataset API.
- Integrate: wire the dataset into Make / Zapier / n8n / Google Sheets / Slack, or POST results to a webhook / warehouse on
RUN_SUCCEEDED.
API examples
Python
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("haketa/bookimed-scraper").call(run_input={"countries": ["turkey"],"cities": ["istanbul", "antalya"],"procedures": ["hair-transplant", "dental-implant"],"language": "us-uk","scrapeDetails": True,"maxClinics": 100,"maxLoadMore": 20,})for clinic in client.dataset(run["defaultDatasetId"]).iterate_items():prices = clinic.get("treatmentPrices") or []cheapest = min((p["min"] for p in prices if p.get("min")), default=None)print(clinic["clinicName"], clinic.get("city"), clinic.get("reviewCount"), "from", cheapest)
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('haketa/bookimed-scraper').call({countries: ['mexico'],cities: ['tijuana', 'cancun'],procedures: ['breast-augmentation', 'liposuction'],maxClinics: 50,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Pulled ${items.length} cosmetic-surgery clinics in Mexico`);
cURL
curl -X POST "https://api.apify.com/v2/acts/haketa~bookimed-scraper/runs?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{ "countries": ["india"], "procedures": ["knee-replacement","hip-replacement"], "maxClinics": 80, "scrapeDetails": true }'
Direct URL mode (anything outside the dropdowns — IVF, gastric sleeve, a single profile):
{"startUrls": [{ "url": "https://us-uk.bookimed.com/clinics/country=spain/procedure=ivf/" },{ "url": "https://us-uk.bookimed.com/clinic/anadolu-medical-center/" }],"scrapeDetails": true}
💡 Tips
- Want rating, reviews and doctors on every clinic? Run with
scrapeDetails: true— the listing card exposes those only sporadically, but each profile reliably surfacesreviews,ratingBreakdown,doctors,descriptionand contact fields. - Combine
cities+proceduresfor laser-targeted lead lists, e.g.{ countries: ["turkey"], cities: ["istanbul"], procedures: ["hair-transplant"] }. - Procedure not in the dropdown? (IVF, gastric sleeve, LASIK, all-on-4…) Paste the listing URL into
startUrls— the actor reads theprocedure=slug straight from the URL. - Sample before you commit — set
maxClinics: 20andscrapeDetails: falsefor a quick, cheap first look, then scale up. - Tripping 403/429? Raise
requestDelayto3000–5000ms and switchproxyConfigurationto residential (recommended for thetr./ru.subdomains). - Local-language content — set
language(e.g.tr,de,ru) to read the regional variant; the actor routes through the matching subdomain.
❓ FAQ
Is scraping Bookimed legal? This actor collects only publicly available marketing content from Bookimed clinic listings — the same pages any visitor sees without logging in. It extracts clinic/business-level data (names, prices, ratings, certifications, named public-facing doctors), not private patient information. You are responsible for ensuring your downstream use complies with applicable laws and Bookimed's terms (GDPR, CCPA, CFAA, ToS).
How many clinics can I scrape, and how fast?
Hundreds per run. Bookimed lists 1,600+ clinics across 50+ countries (300+ in Turkey alone). The latest verification pulled 500 unique clinics in ~5.5 minutes in listing mode. Use maxClinics: 0 + maxLoadMore: 0 for exhaustive collection.
Do I need proxies or a login? No login or API key — all pages are public. Apify Proxy is enabled by default (datacenter), which is enough for most runs; switch to residential if you hit blocks on heavy or localized scraping.
What export formats are supported? JSON, CSV, Excel (XLSX), HTML, XML, RSS and JSON Lines — all from the same run, plus the dataset API.
Is there an API? Yes — the actor is fully controllable via the Apify API and client SDKs (Python/JS). Treat it as your Bookimed API: pass the same JSON input and read the dataset back.
How fresh is the data? Live at run time. Every run fetches current Bookimed pages — there is no cached snapshot, so prices, ratings and review counts reflect what was published the moment the run started.
Can I filter by procedure or city?
Yes — pick from the procedures and cities dropdowns, add free-text cities via citiesCustom, or target any treatment/city by pasting a listing URL into startUrls.
How are treatment prices structured?
Each is an object: { "treatment": "FUE hair transplant", "min": 1800, "max": 2500, "currency": "USD" }. max is null for "from $X" pricing; both USD and EUR are detected and labeled.
Can I get individual patient reviews with full text?
Yes — set scrapeDetails: true. The reviews array returns each review's author, rating (1–5), full text, date, treatment, country and doctor, alongside a ratingBreakdown star distribution. Listing pages expose only aggregate reviewCount/rating; profile mode unlocks the per-review payload.
Why are rating, address, phone, doctors or specialties sometimes null?
In listing mode those are best-effort — Bookimed hydrates them client-side from a Nuxt 3 SPA rather than rendering them in the card text, so the actor leaves them null rather than guess (and never mis-attributes one clinic's data to another). Run with scrapeDetails: true to open each profile, which reliably fills reviews, ratings, doctors, description and contact fields. Fields marked "profile mode only" in the table above are null in listing mode by design.
Does it avoid duplicates across overlapping searches?
Yes — a Set tracks every clinicUrl, so a clinic matching both country=turkey and country=turkey/city=istanbul/procedure=hair-transplant is saved exactly once. The latest run returned 0 duplicates across 500 records.
Does it handle multiple languages?
Yes — set language to one of 13 locales; the actor routes through {lang}.bookimed.com and reads localized "Load More" labels.
How does pay-per-event pricing work? You pay a small fee on actor start plus per dataset item delivered — no monthly minimum, no hidden compute charge. Sampling 20 clinics typically costs pennies.
🔗 Related scrapers
Pair the Bookimed scraper with these adjacent healthcare, directory and B2B data actors by haketa:
- WhatClinic.com Clinic Scraper — global clinic directory for dental, cosmetic, fertility and aesthetic clinics
- BBB Business Scraper — Better Business Bureau ratings, complaints and accreditations
- Texas Pharmacy License Scraper — TSBP — every Texas pharmacist, pharmacy, intern and technician
- California DCA License Scraper — CA Department of Consumer Affairs professional licensing
- Ohio eLicense Scraper — multi-board Ohio professional licensing
- Y Combinator Companies Scraper — YC-backed startup directory for founder, VC and recruiter intel
🧾 Compliance & notes
- Public data only — every field is published on public Bookimed listing/profile pages, accessible without login.
- No patient PII/PHI — reviews surface author display names and public testimonial text only; no private health records are collected.
- Respect rate limits — the actor uses configurable
requestDelay, retry-with-backoff and resource blocking; raise the delay for heavy runs. - Your responsibility — determine whether your downstream use complies with GDPR, CCPA, CFAA and Bookimed's terms of service.
Ready to pull live medical-tourism data? Set your countries, click Start, and export clinic prices, ratings, certifications and reviews to JSON, CSV, Excel or API in minutes. ⭐ If this Bookimed scraper saves your team hours of manual clinic research, a 5-star rating on the Apify Store helps others find it.