Treatwell UK Scraper - Salons, Spas & Barbers
Pricing
from $1.60 / 1,000 venue records
Treatwell UK Scraper - Salons, Spas & Barbers
Scrape Treatwell UK salon, spa and barber listings by city and treatment: ratings, address and coordinates, phone, opening hours, galleries, full service menus with prices, amenities, staff and customer reviews. Search by location or paste venue and results page links.
Pricing
from $1.60 / 1,000 venue records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
12 hours ago
Last modified
Categories
Features
Share
Treatwell UK Scraper: Salons, Spas and Barbers
Treatwell UK Scraper turns Treatwell (treatwell.co.uk) into a clean beauty and wellness data feed. Get salon, spa and barber listings by city and treatment with ratings and sub-scores, full addresses with coordinates, opening hours, photo galleries and service menus with prices and durations. Search by location or paste venue and results page links.
Why This Scraper?
- Two ways in. Search by city and treatment with plain names (haircuts in London, massage in Manchester), or paste Treatwell links: results pages, brand and chain pages, single venue pages and service group pages.
- Rich venue rows. Name, venue type, tags, awards, full address, postcode, map coordinates and phone on every row.
- Ratings with detail. Average rating, review count and the sub-scores, the whole photo gallery and opening hours for all seven weekdays.
- Complete service menus with prices. Every service with sale and full prices, discount flags and durations, plus amenities, staff and a price range per venue.
- Customer reviews on the venue row. The newest reviews (default 20) with reviewer, rating, text, visit date, treatments and staff member, nested on each venue.
- Recurring updates. Run the same search on a schedule and get only new, changed or removed venues.
- Filters that narrow before the limit. Minimum rating and minimum review count are applied before Max items, so a capped run returns qualifying venues only.
Use Cases
- Lead generation for suppliers: build lists of salons, spas and barbers by city and treatment with addresses and ratings.
- Market research: map venue density, price ranges and ratings across UK cities and treatment types.
- Price benchmarking: compare service prices, discounts and durations across venues.
- Local SEO and directories: enrich a directory with photos, opening hours and coordinates.
- AI agents and dashboards: feed structured venue data into your own tools.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
venueId | 100000 |
name / businessName | "Sample Hair Studio" |
url / placeUrl | Link to the venue page |
businessType / category / subCategory | "Hair Salon" / "Hair" / "Beauty Salon" |
tags / accolades | ["Top Rated 2026", "Hair Salon"] / ["Top Rated 2026"] |
address / street / city / region | full address / "1 Sample Road" / "London" / "London" |
postalCode / country / countryCode | "AA1 1AA" / "United Kingdom" / "GB" |
latitude / longitude / coordinates / location | 51.5 / -0.12 / { "lat": 51.5, "lon": -0.12 } / address, coordinates, postal code and area |
rating | average, count and per-dimension scores |
ratingValue / reviewCount / ratingDimensions | 4.6 / 120 / Cleanliness, Staff, Ambience scores |
imageUrl / images | main photo / full gallery |
openingHours | seven weekdays with open flag and times |
descriptionHtml / basicInfo | description as HTML / id, name, description text, venue link |
services / allServices | name, description, prices, discount, duration, categories |
treatments / topTreatments / priceFrom / priceTo / priceRange / currency | service names / top three / 10 / 90 / "£10 - £90" / "GBP" |
newVenue / mobile | false / false |
phone | Venue phone number |
chainName / chainId / chainUrl | Chain the venue belongs to, when it does |
amenities / amenityGroups | ["Free Wifi", "Wheelchair access"] / the same grouped |
staff | Team members with name, title and photo |
menu / menuItemCount | Complete menu grouped by section, with prices and durations / number of services |
reviews / reviewsDelivered | Nested customer reviews, newest first / how many are on the row |
publishedDate / searchUrl / scrapedAt | Listing date / the page the venue came from / collection time |
changeType / changedFields / firstSeenAt / lastSeenAt | Incremental mode only |
How to Use
- Pick a mode:
searchfor city and treatment, orurlfor pasted results page links. - For search, enter one or more locations and optional treatments. For links, paste Treatwell results pages, or leave the shipped example in place for a first test run.
- Set Max items to control run size, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Search by city and treatment:
{"mode": "search","locations": ["London"],"treatments": ["Haircuts and hairdressing"],"maxItems": 20}
Best discounts in several cities, well-rated only:
{"mode": "search","locations": ["Manchester", "Leeds"],"sortBy": "DISCOUNT","minRating": 4.5,"minReviews": 50,"maxItems": 40}
Paste any Treatwell link (results page, brand page, chain page, venue page or service group page):
{"mode": "url","urls": ["https://www.treatwell.co.uk/places/brand-olaplex/in-london-uk/","https://www.treatwell.co.uk/place/lili-london/","https://www.treatwell.co.uk/hairdressers-and-hair-salons/"],"maxItems": 30}
Daily monitoring of one search (only what changed):
{"mode": "search","locations": ["London"],"treatments": ["Haircuts and hairdressing"],"incrementalMode": true,"maxItems": 200}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/treatwell-co-uk-scraper").call(run_input={"mode": "search", "locations": ["London"], "maxItems": 20})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["name"], item["ratingValue"], item["reviewCount"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/treatwell-co-uk-scraper').call({ mode: 'search', locations: ['London'], maxItems: 20 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Locations and treatments
Locations are UK cities or areas typed as plain names (London, Manchester, Clapham London). Leave them empty or type UK to search the whole country. Treatments accept plain names (Massage, Gel nails) or slugs; several treatments are combined into one search. A name that does not match is reported in the run log, and a run where nothing matches fails with a message instead of returning an empty dataset; paste a results page link in URL mode as the fallback.
Which links work in URL mode
Results pages (/places/... with a treatment and city, an optional sort and page-N), brand, chain and venue-type pages, single venue pages (/place/...) and service group pages such as /hairdressers-and-hair-salons/. A results page continues forward from the page in the link, and a link without its own sort uses the Sort results by input. Other pages (home, gift cards, information pages, other countries) are skipped with a warning.
Reviews
With full details on, each venue carries its newest reviews (Max reviews per venue, default 20, 0 skips them). Reviews are nested on the venue row, never separate dataset items.
Recurring updates (incremental mode)
Turn on Incremental changes for scheduled runs to run the same search every day and receive only NEW, UPDATED and REAPPEARED venues. changedFields names what changed. A new review alone does not make a venue UPDATED; a change in reviewCount or rating does. Venues that disappeared are returned as EXPIRED once a run has scanned the whole search (not when Max items, Max pages or Resume cut it short). Emit unchanged venues returns the unchanged rows as well. Venues left out as unchanged are neither returned nor billed. Resume from a previous run continues one interrupted run by its run or dataset id.
How maxItems shapes a run
Results come in pages of 20 venues. A run stops once maxItems is reached. With several locations the limit is shared evenly so every location gets a turn. Set maxItems to 0 to collect everything the searches return.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest.
- Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
At most maxNotifyListings items (default 50) are written to each connector per run; this cap never affects the dataset. The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip the export.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search by location and treatment, or url for pasted results page links. |
locations | array | ["London"] | UK cities or areas (search mode). Empty or UK means the whole country. |
treatments | array | (none) | Treatment names or slugs; several are combined into one search. Empty means every venue type. |
sortBy | string | RECOMMENDED | RECOMMENDED, PRICE_ASC, PRICE_DESC or DISCOUNT. |
minRating | number | (none) | Keep venues with an average rating at or above this value, applied before Max items. |
minReviews | integer | (none) | Keep venues with at least this many reviews, applied before Max items. |
urls | array | one link per kind | Treatwell venue, results, brand, chain and group page links (URL mode). Results start from the page in the link. |
fetchDetails | boolean | true | Include phone, amenities, staff, the complete menu, full gallery, description and reviews. Off gives compact rows. |
maxReviews | integer | 20 | Reviews per venue, newest first (0 skips, up to 1000). Needs full details on. |
maxPages | integer | unlimited | Results pages per search; blank or 0 means unlimited and does not cap results. |
maxItems | integer | 20 | Stop after this many venues (0 means no limit). The only result limit. |
proxy | object | Apify proxy | Connection settings (see Plan Requirement). |
resumeFromRunId | string | (none) | Continue one interrupted run by its run or dataset id. |
incrementalMode | boolean | false | Return only new, updated and reappeared venues on repeat runs. |
stateKey | string | (auto) | Name a monitoring campaign (incremental mode). |
emitUnchanged | boolean | false | Also return unchanged venues (incremental mode). |
emitExpired | boolean | true | Return venues that disappeared after a complete scan (incremental mode). |
ignoreFieldsForChanges | array | (none) | Fields that never count as a change (incremental mode). |
mcpConnectors | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which records are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
Venue record:
{"venueId": 100000,"name": "Sample Hair Studio","url": "https://www.treatwell.co.uk/place/sample-hair-studio/","businessType": "Hair Salon","category": "Hair","subCategory": "Beauty Salon","tags": ["Top Rated 2026", "Hair Salon"],"address": "1 Sample Road, Sample Area, London, AA1 1AA","city": "London","postalCode": "AA1 1AA","country": "United Kingdom","latitude": 51.5,"longitude": -0.12,"rating": { "average": 4.6, "count": 120, "dimensions": [{ "name": "Staff", "average": 4.6, "count": 100 }] },"ratingValue": 4.6,"reviewCount": 120,"openingHours": [{ "day": "monday", "open": true, "from": "09:00", "to": "18:00" }],"services": [{ "name": "Haircut and blow dry", "priceFrom": 40, "priceTo": 60, "durationMinutesFrom": 60, "durationMinutesTo": 75 }],"priceFrom": 10,"priceTo": 90,"priceRange": "£10 - £90","currency": "GBP"}
Plan Requirement
The default connection is Apify Proxy, and it needs a plan that includes proxy access. The actor tries these connections in order and tells you in the run log what it used:
- Apify datacenter proxy (the default).
- Apify residential proxy, tried when the datacenter connection is refused or fails. Apify free plans do not include residential proxies.
- A backup residential connection.
- A backup datacenter connection as the last resort.
What you will see in the run log:
- When the residential connection is refused for your account, a boxed warning once: "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable. For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs."
- When a request is served by a backup connection: "Served over the backup connection (the default connection was unavailable)."
A run that could not read any page ends as failed, never as an empty success, with one of these messages:
- Every connection refused: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required: https://apify.com/pricing. If you entered your own proxy URLs, check that their credentials are valid."
- Free plan, backup connection reachable but no usable page: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Treatwell pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again."
- Any other run where no page loaded: "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later."
FAQ
How much does it cost?
You pay per venue returned, plus a detail charge for each venue returned with full details and a charge for each review returned on it. Switch Include full details off for a compact row with neither. The charges are only for rows you actually receive: in incremental mode, unchanged venues left out are not billed. The Pricing tab shows the current rates. Use Max items and Max reviews per venue to cap the cost of any run.
Is it legal to scrape Treatwell?
This actor collects only publicly available listing data: venue names, addresses, ratings, opening hours, photos and service prices. You are responsible for how you use it: follow Treatwell's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution.
Can I run it on a schedule?
Yes. Schedule the actor from the Schedules tab with the same input to refresh a city on a regular basis.
Why did a run return fewer venues than the website shows?
The run stops at Max items, and the minimum rating and review filters remove venues that do not qualify. Raise the limit, or set it to 0, to collect more.
Why did my run fail instead of returning an empty dataset?
If not a single page could be read, the run fails with a message describing the connection problem, so "no results" is never confused with "nothing could be read". Try again later or switch the Connection setting.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
🔗 More scrapers you might like
Pair this actor with these related scrapers from the same team:
| 🧩 Fresha Scraper Scrape Fresha salon and spa listings: business profiles, service menus with prices and... | 🧩 Booksy Scraper Scrape Booksy beauty businesses across the US, UK and Poland by category, location or... |
| 🏠 Rightmove UK Scraper Fast, reliable Rightmove.co.uk scraper for UK properties for sale, rent and sold-price... | 🔌 Currys UK Scraper Scrape Currys UK products, including electronics, home appliances, computers, TVs and... |
| 💼 Jobsite UK Scraper Scrape Jobsite.co.uk job listings at scale by keyword, location, filters or URL. Extract... | 🧩 Zoopla Scraper Scrape UK property from Zoopla: for sale, to rent and Land Registry sold prices. Search... |
💬 Support
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.