Fresha.com Scraper - Salon & Spa Data Extractor avatar

Fresha.com Scraper - Salon & Spa Data Extractor

Pricing

from $0.70 / 1,000 results

Go to Apify Store
Fresha.com Scraper - Salon & Spa Data Extractor

Fresha.com Scraper - Salon & Spa Data Extractor

Extract salon, spa & beauty business data from Fresha.com. Scrape services with prices, reviews, team members, ratings, and operating hours. Search by city or neighborhood worldwide (Dubai, London, NYC, etc.). Perfect for market research, lead generation, price comparison, and chatbot integration.

Pricing

from $0.70 / 1,000 results

Rating

0.0

(0)

Developer

Malik Mazhar Ali

Malik Mazhar Ali

Maintained by Community

Actor stats

0

Bookmarked

43

Total users

6

Monthly active users

4.6 days

Issues response

15 days ago

Last modified

Share

Fresha Scraper - Salon & Spa Data Extractor

Extract salon, spa, and beauty service data from Fresha.com - the world's largest booking platform for beauty and wellness services.

This Actor supports two powerful modes for different use cases:

Features

  • Complete service catalog — every service captured via real-browser booking-flow fetch
  • Two scraping modes: venue (deep) and search (discovery)
  • Up to 1000 venues per search run
  • Multi-category aggregation — search all 10 Fresha categories at once
  • Customer reviews with ISO 8601 dates and reviewsSince for incremental pipelines
  • Review reply text and author (including business owner replies)
  • Day-by-day operating hours
  • GPS coordinates and Google Maps URL
  • Team members with roles and ratings
  • Packages and bundled service offers
  • Three output formats: full / services-only / chatbot-optimised (WhatsApp / n8n)
  • Webhook integration (n8n, Make, Zapier)
  • CSV / Excel exports via dataset views (services, team, reviews)
  • Resilience: graceful fallback with partial: true flag — never returns zero
  • No proxy required

What Data Can You Extract?

Data TypeVenue ModeSearch Mode
Business name & details
Services with prices✅ (full list)
Operating hours
Team members & ratings
Customer reviews
Overall rating
Review count
Location/address
Direct booking URL
Packages & offers

Mode 1: Venue Scraping (Specific Business)

Best for: Getting complete details about specific salons you already know.

Scrape detailed information from specific Fresha venue pages including all services, prices, team members, reviews, and operating hours.

Example Input

{
"mode": "venue",
"venueUrls": [
"https://www.fresha.com/a/sofitel-spa-dubai-downtown-dubai-sofitel-dubai-downtown-sheikh-zayed-rd-downtown-dubai-4s5674wx",
"https://www.fresha.com/a/jalal-hafed-gents-salon-dubai-building-6-al-raya-street-city-walk-dubai-z0atp2ev"
],
"outputFormat": "full",
"includeReviews": true,
"includeTeam": true,
"maxReviews": 10
}

Example Output (Full Format)

{
"venueName": "Sofitel Spa Dubai Downtown",
"url": "https://www.fresha.com/a/sofitel-spa-dubai-downtown...",
"description": "Experience luxury wellness at Sofitel Spa...",
"phone": "+971 4 503 6666",
"rating": 4.9,
"reviewsCount": 1156,
"currency": "AED",
"priceMin": 150,
"priceMax": 2500,
"serviceCount": 47,
"hours": {
"Monday": ["10:00 AM - 10:00 PM"],
"Tuesday": ["10:00 AM - 10:00 PM"]
},
"categories": [
{
"name": "Massage",
"services": [
{
"name": "Swedish Massage",
"price": "AED 450",
"duration": "1 hr",
"priceValue": 450
},
{
"name": "Deep Tissue Massage",
"price": "AED 550",
"duration": "1 hr",
"priceValue": 550
}
]
},
{
"name": "Facial Treatments",
"services": [...]
}
],
"packages": [
{
"name": "Couples Retreat",
"price": "AED 1200",
"discount": { "description": "Save 20%", "value": 300 },
"includes": ["Couples Massage", "Facial", "Spa Access"]
}
],
"team": [
{
"name": "Maria",
"role": "Spa Therapist",
"rating": 4.9
}
],
"reviews": [
{
"rating": 5,
"comment": "Amazing spa experience, highly recommend!",
"author": "Ahmed",
"date": "Jan 15, 2026"
}
]
}

Output Formats

FormatDescriptionBest For
fullAll venue data including raw fieldsData analysis, backup
services_onlyJust services and pricesPrice comparison
chatbot_optimizedCompact format for AI processingWhatsApp bots, n8n chatbots

Mode 2: Search (By Location)

Best for: Discovering salons in a location - either by category or across all categories.

Search for salons and spas by location. Select a specific category or choose "All Categories" for maximum discovery.

Option A: Search Specific Category

{
"mode": "search",
"searchLocation": "Dubai, UAE",
"serviceCategory": "spa",
"maxSearchResults": 50
}

Output:

{
"searchQuery": {
"location": "Dubai, UAE",
"serviceCategory": "spa",
"totalFound": 156,
"resultsReturned": 6
},
"venues": [
{
"name": "Sofitel Spa Dubai Downtown",
"slug": "sofitel-spa-dubai-downtown-dubai-sofitel-dubai-downtown-sheikh-zayed-rd-downtown-dubai-4s5674wx",
"url": "https://www.fresha.com/a/sofitel-spa-dubai-downtown...",
"rating": 4.9,
"reviewsCount": 1156,
"location": "Downtown Dubai, Dubai"
}
],
"scrapedAt": "2026-01-23T08:01:20.527Z"
}

Option B: Search All Categories (Maximum Discovery)

Select "All Categories" in the dropdown (or leave empty) to automatically search all 10 service categories with automatic deduplication.

{
"mode": "search",
"searchLocation": "Dubai, UAE",
"serviceCategory": "",
"maxSearchResults": 100
}

Output:

{
"searchQuery": {
"location": "Dubai, UAE",
"mode": "multi-category",
"categoriesSearched": 10,
"totalUniqueFound": 24,
"resultsReturned": 24
},
"categoryBreakdown": {
"spa": { "found": 6, "new": 6 },
"hair-salon": { "found": 6, "new": 4 },
"barbershop": { "found": 4, "new": 3 },
"nail-salon": { "found": 5, "new": 2 },
"beauty-salon": { "found": 6, "new": 3 },
"massage": { "found": 4, "new": 1 },
"skin-care": { "found": 5, "new": 2 },
"brows-lashes": { "found": 6, "new": 2 },
"makeup": { "found": 4, "new": 1 },
"waxing": { "found": 5, "new": 0 }
},
"venues": [
{
"name": "Sensasia Emirates Golf Club",
"slug": "sensasia-emirates-golf-club-dubai-...",
"url": "https://www.fresha.com/a/sensasia-emirates-golf-club-dubai-...",
"rating": 4.9,
"reviewsCount": 2017,
"discoveredInCategory": "spa"
}
],
"scrapedAt": "2026-01-23T08:30:00.000Z"
}

Search Mode Comparison

Category SelectionUnique VenuesTimeBest For
Specific category4-10~30 secQuick category lookup
All Categories15-40+~5 minComprehensive discovery

Fresha's search page uses a map-centric design:

  • The "X venues nearby" count refers to map markers, not a scrollable list
  • The list view only shows 6-10 featured/promoted venues per category
  • Selecting "All Categories" maximizes discovery by searching all 10 categories

This is a Fresha platform limitation, not a scraper limitation.

// Step 1: Discover venues with "All Categories" search
{ "mode": "search", "searchLocation": "Dubai, UAE", "serviceCategory": "" }
// Step 2: Scrape full details for discovered venues
{
"mode": "venue",
"venueUrls": [
"https://www.fresha.com/a/sensasia-emirates-golf-club-dubai-...",
"https://www.fresha.com/a/curve-beauty-salon-dubai-..."
]
}

Available Service Categories

  • hair-salon - Hair salons
  • barbershop - Barbershops
  • nail-salon - Nail salons
  • spa - Spas
  • beauty-salon - Beauty salons
  • massage - Massage therapy
  • skin-care - Skin care
  • brows-lashes - Brows & lashes
  • makeup - Makeup services
  • waxing - Waxing services

Supported Locations (Optimized)

The scraper includes GPS coordinates for accurate results in:

  • UAE: Dubai, Abu Dhabi
  • Saudi Arabia: Riyadh, Jeddah
  • Qatar: Doha
  • Kuwait: Kuwait City
  • Bahrain: Manama
  • Oman: Muscat

Other locations work but may have less accurate results depending on proxy IP.


Input Parameters Reference

Common Parameters

ParameterTypeDefaultDescription
modestringvenueScraping mode: venue (specific business) or search (by location)
webhookUrlstring-URL to POST results after scraping
proxyConfigurationobjectAutoProxy settings (not required for Fresha)

Venue Mode Parameters

ParameterTypeDefaultDescription
venueUrlsarray-List of Fresha venue URLs
venueSlugstring-Single venue slug (alternative)
includeReviewsbooleantrueInclude customer reviews
includeTeambooleantrueInclude team members
maxReviewsinteger10Max reviews to include (0 = all available)
reviewsSincestring-ISO 8601 date (e.g. 2026-04-14). Only returns reviews newer than this. Ideal for incremental Mon/Wed/Fri pipelines.
outputFormatstringfullfull / services_only / chatbot_optimized

Search Mode Parameters

ParameterTypeDefaultDescription
searchLocationstring-Location to search (required)
serviceCategorystring""Category: empty for all categories (30-60+ venues), or specific category
maxSearchResultsinteger50Max venues to return (1–1000). Values above 500 take 10–20 min and use the actor's default 4 GB memory.

Review Object Schema

Each review in reviews[] always contains all of these keys — null is used where Fresha doesn't supply a value, so pipelines can destructure safely:

FieldTypeNotes
idstringFresha review ID
ratinginteger 1–5Always present
commentstring | nullnull for rating-only reviews
dateISO 8601 UTCe.g. 2026-04-16T22:34:00.000Z — parseable by new Date()
dateFormattedstring | nullHuman-readable, e.g. Thu, Apr 16, 2026 at 10:34 PM
authorstring"Anonymous" if redacted
employeeNamestring | nullStaff member who delivered the service, if attributed
replyobject | null{ text, date, author } when the salon replied

Reviews are returned newest-first as provided by Fresha's API.


Integration with n8n

This Actor is designed for seamless integration with n8n workflows.

  1. Install the Apify node in n8n (if not already installed)

  2. Create Apify API Token:

    • Go to Apify Console → Settings → API & Integrations
    • Create a new API token and copy it
  3. Configure n8n Apify Node:

    For Venue Mode:

    Node: Apify
    Operation: Run Actor
    Actor ID: malikgen/fresha-scraper
    Input Body:
    {
    "mode": "venue",
    "venueUrls": ["https://www.fresha.com/a/sofitel-spa-dubai-downtown-dubai-sofitel-dubai-downtown-sheikh-zayed-rd-downtown-dubai-4s5674wx"],
    "outputFormat": "chatbot_optimized",
    "includeReviews": true,
    "maxReviews": 5
    }

    For Search Mode:

    Node: Apify
    Operation: Run Actor
    Actor ID: malikgen/fresha-scraper
    Input Body:
    {
    "mode": "search",
    "searchLocation": "Dubai, UAE",
    "serviceCategory": "spa",
    "maxSearchResults": 20
    }
  4. Get Results:

    • Add another Apify node with Operation: "Get Dataset Items"
    • Connect it to get the scraped data

Option 2: Using HTTP Request Node

If you prefer not to use the Apify node, you can use HTTP requests:

  1. Start the Actor Run:

    Node: HTTP Request
    Method: POST
    URL: https://api.apify.com/v2/acts/malikgen~fresha-scraper/runs?token=YOUR_API_TOKEN
    Body Type: JSON
    Body:
    {
    "mode": "venue",
    "venueUrls": ["https://www.fresha.com/a/sofitel-spa-dubai-downtown-dubai-sofitel-dubai-downtown-sheikh-zayed-rd-downtown-dubai-4s5674wx"],
    "outputFormat": "chatbot_optimized"
    }
  2. Wait for Completion (add Wait node):

    • Add a Wait node: 30-60 seconds for venue mode, 2-3 minutes for search mode
  3. Get Results:

    Node: HTTP Request
    Method: GET
    URL: https://api.apify.com/v2/acts/malikgen~fresha-scraper/runs/last/dataset/items?token=YOUR_API_TOKEN

Option 3: Using Webhooks (Real-time)

Configure the Actor to POST results directly to your n8n webhook:

  1. Create n8n Webhook:

    • Add a Webhook node in n8n
    • Copy the webhook URL
  2. Run Actor with Webhook:

    {
    "mode": "venue",
    "venueUrls": ["https://www.fresha.com/a/sofitel-spa-dubai-downtown-dubai-sofitel-dubai-downtown-sheikh-zayed-rd-downtown-dubai-4s5674wx"],
    "webhookUrl": "https://your-n8n-instance.com/webhook/fresha-results"
    }
  3. Webhook Payload Structure:

    {
    "source": "fresha-scraper",
    "timestamp": "2026-01-23T12:00:00Z",
    "data": { /* scraped venue or search data */ }
    }

Complete n8n Workflow Example: WhatsApp Salon Assistant

[WhatsApp Trigger]
[Check if cached data < 1 hour]
[If stale: Run Fresha Scraper]
[OpenAI: Process data and user query]
[Send WhatsApp response with service info]

Workflow Steps:

  1. WhatsApp Trigger: Receives user message like "What massage services does Sofitel Spa offer?"

  2. Check Cache: Query your database/Redis for recent data

  3. Run Scraper (if needed):

    • Use Apify node with chatbot_optimized format
    • This format is compact and AI-friendly
  4. AI Processing:

    • Send scraped data + user question to OpenAI/Claude
    • Get formatted response
  5. Send Reply: Return service info to WhatsApp


Technical Details

Performance

  • Venue mode: ~15-30 seconds per venue (real-browser fetch ensures complete service catalog)
  • Search mode: ~30-90 seconds (browser-based, handles JavaScript)

Proxy Recommendations

GOOD NEWS: No proxy is required! Fresha.com works perfectly without any proxy configuration.

Our testing shows:

Proxy TypeDurationCostRecommendation
No Proxy~25s$0.004BEST - Use this!
Datacenter~72s$0.012Works but slower
Residential~119s$0.042Not needed, expensive

Bottom line: Leave proxy configuration empty/disabled for the best performance and lowest cost. Fresha.com does not have aggressive anti-bot measures.

Rate Limiting

The Actor includes built-in delays and respects Fresha's servers with reasonable request rates.


Use Cases

  1. Price Comparison: Compare service prices across multiple salons
  2. Market Research: Analyze salon ratings and reviews in a region
  3. Chatbot Integration: Power WhatsApp/Telegram bots with real salon data
  4. Lead Generation: Find salons for B2B outreach
  5. Competitive Analysis: Monitor competitor pricing and services
  6. Booking Aggregator: Build salon discovery platforms

Support & Resources


Changelog

v0.1.6 (Current)

  • FIXED: Incomplete service catalogs. Fresha's SSR ships only the initial Apollo cache snapshot (typically 55–70 % of services for deep catalogs). v0.1.6 switches venue mode to Playwright-first with booking-page GraphQL interception — the bookingFlowInitialize response contains the full service catalog. Classic Manicure and other previously missing services are now captured.
  • NEW: extractionPath field. Values: playwright (SSR was complete), playwright+booking (booking-page fetch used), cheerio-fallback, jsonld-fallback.
  • NEW: extractedServiceCount field. Actual number of services extracted for easy comparison against serviceCount (venue's reported total).
  • NEW: partial field. false when Playwright succeeded; true on fallback paths.
  • RELIABILITY: 3-level fallback chain. Playwright → Cheerio on captured HTML → JSON-LD metadata. Never returns zero.

v0.1.5

  • FIXED: Search returning ~6 venues instead of requested count. Root cause: greedy extractTotalVenuesCount regex matched any small number on the page and capped the scroll target. Now always uses maxSearchResults as the target.
  • FIXED: 120 s timeout when collecting 100+ venues. Bumped requestHandlerTimeoutSecs to 1200 (20 min), set maxRequestRetries: 0 (retries restart the page from scratch and lose all scroll progress), wrapped the scroll in try/catch with DOM salvage so partial results are always saved.
  • NEW: 1000-venue ceiling. maxSearchResults raised from 200 to 1000. Internal soft time-budget (17.5 min) ensures page.evaluate() exits cleanly with whatever was collected before Node-side timeout fires.
  • NEW: ISO 8601 review dates. review.date is now ISO 8601 UTC (2026-04-16T22:34:00.000Z); the human-readable string is preserved as review.dateFormatted.
  • NEW: reviewsSince input parameter. ISO date string filters reviews to only those newer than the given date — perfect for incremental Mon/Wed/Fri pipelines.
  • PERF: Scroll cadence tuned for 1k. scrollDelay 800 → 500 ms, maxScrollAttempts 500 → 1500, MAX_NO_NEW_STREAK 20 → 25.
  • MEMORY: 2–4 GB allocation. minMemoryMbytes 512 → 2048, maxMemoryMbytes 2048 → 4096. Prevents the 95 %-pressure stalls observed at 1 GB during 100+ venue runs.
  • VERIFIED: City of London + hair-salon @ maxResults=100 → 100 venues in 44 scrolls (~30 s, no timeout).

v0.1.20

  • SIMPLIFIED: Merged 3 modes into 2 modes for cleaner UX
    • venue - Scrape specific business (unchanged)
    • search - Search by location (now includes "All Categories" option)
  • IMPROVED: Category dropdown now clearly shows "All Categories (searches all 10, discovers 30-60+ venues)"
  • UPDATED: Venue URL placeholder uses Dubai salon example
  • REMOVED: search-all mode (legacy support maintained for backward compatibility)
  • Categories are based on Fresha.com's official URL parameters

v0.1.18

  • FIXED: Search mode now collects 90+ venues instead of only 4-6
  • Implemented incremental scroll-and-collect strategy to handle DOM virtualization
  • Confirmed: No proxy required - Fresha works perfectly without proxy (fastest & cheapest)
  • Added memory limits (512MB min, 2GB max) for cost optimization

v0.1.17

  • NEW: Search-All Mode - Multi-category search for maximum venue discovery
  • Automatically searches all 10 service categories and deduplicates results
  • Discovers 15-40+ unique venues instead of 4-10 per single search
  • Added category breakdown in output showing discovery stats

v0.1.16

  • Updated examples to use Dubai, UAE
  • Improved documentation for search mode limitations
  • Added two-step discovery workflow guide

v0.1.14

  • Improved location extraction accuracy
  • Better handling of Arabic text
  • Enhanced error handling for search mode
  • Comprehensive n8n integration documentation

v0.1.0

  • Added search mode with PlaywrightCrawler
  • Dual-mode architecture (venue + search)
  • GCC region geolocation support
  • Webhook integration for n8n

v0.0.1

  • Initial release
  • Venue scraping with CheerioCrawler
  • Multiple output formats