Fragrantica Scraper — Perfume Profiles & Notes
Pricing
from $6.00 / 1,000 fragrantica perfume profile scrapeds
Fragrantica Scraper — Perfume Profiles & Notes
Extract structured Fragrantica perfume profiles with brand, perfumer, note pyramid, main accords, rating, launch year, and source provenance. Use only with Fragrantica authorization. MCP-ready. $0.006 per saved profile.
Pricing
from $6.00 / 1,000 fragrantica perfume profile scrapeds
Rating
0.0
(0)
Developer
Khadin Akbar
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
a day ago
Last modified
Categories
Share
Extract structured perfume profiles from authorized Fragrantica product pages. The actor turns individual /perfume/...html URLs into comparison-ready JSON records containing the perfume name, brand, credited perfumer, launch year, main accords, top/middle/base notes, visible rating fields, bottle image, editorial description, and source provenance.
Use this actor for licensed fragrance-data research, catalog enrichment, assortment comparison, trend analysis, and internal product intelligence. It is deliberately narrow: v0.1 handles perfume profile pages, not search pages, designer pages, forums, or bulk review collection. That keeps its output stable for API and MCP consumers.
Authorization and permitted use
Run this actor only where you have written authorization from Fragrantica or another applicable legal basis to access and commercially use the requested data. You are responsible for ensuring your input URLs, storage, downstream use, and redistribution comply with your agreement and applicable law. The actor does not accept login cookies, credentials, or attempts to circumvent access controls. If Fragrantica returns a Cloudflare challenge instead of a product page, the run reports an honest upstream failure rather than treating it as empty data.
When to use it
Use this actor when you already have one or more authorized Fragrantica perfume URLs and need structured fields for a database, spreadsheet, RAG index, comparison workflow, or AI-agent task. Provide a full product URL such as:
https://www.fragrantica.com/perfume/Aramis/Tuscany-Per-Uomo-123.html
Do not use it for perfume discovery from a keyword, extracting every fragrance by a designer, collecting community reviews, or scraping Fragrantica pages outside the /perfume/ route. Those uses are out of scope for this initial private build.
Output
Each dataset item is a normalized perfume profile. Fields are stable and documented in .actor/dataset_schema.json.
| Field | Description |
|---|---|
name, brand, brandUrl | Perfume identity and designer provenance |
productId, sourceUrl, scrapedAt | Stable source identifiers and extraction time |
gender, fragranceFamily, launchYear | Core classification fields when present |
perfumers | Credited nose or noses from the profile description |
mainAccords | Ordered Fragrantica main accords |
topNotes, middleNotes, baseNotes | Note pyramid arrays |
rating, ratingCount | Visible user-rating fields when reliably present |
description, imageUrl | Editorial profile text and primary bottle image URL |
Example record:
{"sourceUrl": "https://www.fragrantica.com/perfume/Aramis/Tuscany-Per-Uomo-123.html","productId": "123","name": "Tuscany Per Uomo Aramis for men","brand": "Aramis","gender": "men","fragranceFamily": "Aromatic Fougere","launchYear": 1984,"perfumers": ["Francis Deleamont"],"mainAccords": ["citrus", "aromatic", "fresh spicy"],"topNotes": ["Lemon", "Lavender", "Bergamot", "Lime"],"middleNotes": ["Anise", "Caraway", "Tarragon", "Orange Blossom"],"baseNotes": ["Leather", "Oakmoss", "Basil", "Patchouli"],"rating": null,"ratingCount": null,"scrapedAt": "2026-07-14T12:00:00.000Z"}
Null values mean a field was not reliably displayed on that profile; empty arrays mean the corresponding note or accord list was not present. The actor never substitutes invented data for a missing field.
Input
startUrls is an array of one or more authorized Fragrantica perfume URLs. Every URL must use HTTPS, host www.fragrantica.com or fragrantica.com, begin with /perfume/, and end in .html. Invalid URLs are skipped when valid URLs remain; a run with no valid input exits successfully as INVALID_INPUT with a clear diagnostic in OUTPUT and RUN_SUMMARY.
maxResults is a strict 1–100 cap on saved perfume records. The actor deduplicates repeated URLs before requesting them and never writes or bills more profile records than the cap. proxyCountryCode selects the Apify Residential proxy country (US, GB, or DE). useApifyProxy defaults to true and should stay enabled for cloud runs because Fragrantica may challenge direct automation traffic.
Price and cost visibility
This private actor uses Pay per event + usage. The event charges are:
- Actor start: $0.00005 after valid input is accepted.
- Validated perfume profile saved: $0.006 per record.
Apify platform usage, including Residential Proxy usage, is charged separately to the user. Before any request, the run status message displays the maximum event-charge estimate implied by the cap. A one-profile run has event charges of approximately $0.00605 plus platform usage; five profiles have event charges of approximately $0.03005 plus platform usage. Profiles are charged only when a validated dataset row is persisted.
Terminal outcome contract
The actor writes both OUTPUT and RUN_SUMMARY into the default key-value store for every terminal path. API and MCP consumers should read OUTPUT for the compact, stable summary and RUN_SUMMARY for safe diagnostics.
COMPLETE: all requested valid profiles were saved.PARTIAL: useful profiles were saved, but some URLs failed, were invalid, or the event cap stopped additional work.VALID_EMPTY: valid pages were processed but yielded no usable profile.INVALID_INPUT: the request contains no valid Fragrantica perfume URL or an invalid cap.UPSTREAM_FAILED: Fragrantica returned challenges or requests failed after retries and no useful profile was saved.CONFIG_ERROR: a required deployment configuration is unavailable.
The first four outcomes finish as SUCCEEDED; the last two finish as FAILED so an upstream outage is never hidden behind a false success.
JavaScript example
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('khadinakbar/fragrantica-scraper').call({startUrls: [{url: 'https://www.fragrantica.com/perfume/Aramis/Tuscany-Per-Uomo-123.html',}],maxResults: 1,proxyCountryCode: 'US',});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
cURL example
curl -X POST "https://api.apify.com/v2/acts/khadinakbar~fragrantica-scraper/runs?token=$APIFY_TOKEN" \-H "content-type: application/json" \-d '{"startUrls": [{"url": "https://www.fragrantica.com/perfume/Aramis/Tuscany-Per-Uomo-123.html"}],"maxResults": 1,"proxyCountryCode": "US"}'
Reliability and data quality
The crawler uses a consistent Residential proxy session, bounded retries, a single-request concurrency setting, and a semantic parser based on visible headings and note links. Every candidate record is normalized and validated before Actor.pushData writes it and charges the profile-scraped event. That coupling prevents billing a record that was not persisted. The actor records request errors, invalid records, warnings, terminal counts, and charge counts without exposing URLs with query parameters, cookies, authorization headers, or other secrets.
Fragrantica can change its markup or bot protection. The release process therefore includes a private cloud acceptance matrix across valid profile URLs, invalid input, result caps, proxy countries, concurrency, cold/warm runs, and data-schema checks. The release report records the observed canary sample rather than claiming it proves long-term production reliability.
Support boundary
For an authorized production use case that needs search, designer catalogs, reviews, historical change tracking, or a licensed API integration, extend the private actor only after confirming those capabilities are covered by the Fragrantica authorization. Keep any new mode behind a schema field, an explicit output contract, and a new cloud acceptance matrix.