# Fragrantica Scraper - Perfume Notes, Accords, Ratings (`scrapewise/fragrantica-scraper`) Actor

Scrape Fragrantica perfumes by keyword, brand, note, family, perfumer, gender and year: note pyramid, accords with strength, rating, votes, reviews, perfumers, launch year, description and similar perfumes. Perfume and designer links work. Error rows are free.

- **URL**: https://apify.com/scrapewise/fragrantica-scraper.md
- **Developed by:** [Scrapewise Data](https://apify.com/scrapewise) (community)
- **Categories:** E-commerce, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 perfume delivereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Fragrantica Scraper: perfume notes, accords, ratings, votes and perfumers

Fragrantica Scraper collects **perfumes from fragrantica.com**, the largest perfume encyclopedia. Search by keyword,
or filter by brand, note, olfactory family, perfumer, gender, launch year and number of votes, or paste perfume and
designer links. Each perfume comes back as one clean row: name, brand, launch year, gender, collection, average
rating, rating votes and reviews, image, and (by default) the full note pyramid (top, middle, base), the main accords
with their strength from 0 to 100, the olfactory family, the perfumers, the description and the perfumes people also
like. No account or cookies are needed.

It is used to build fragrance databases and recommendation engines, to compare a brand's line-up, to research which
notes and accords are trending in new launches, to feed dupe and "smells like" finders, to enrich e-commerce
catalogs with notes and ratings, and as structured data for AI assistants.

### At a glance

| What | Price |
|---|---|
| Perfume delivered | **US$ 2.00 per 1,000 perfumes** (US$ 0.002 each) |
| Run start | US$ 0.005 per run |

- 500 perfumes with notes and accords = **US$ 1.005**.
- Error rows and duplicates are never charged. `maxItems` is a hard cap, and a spending limit set on the run stops it
  cleanly with everything delivered so far.
- With `includeDetails` off a run returns about 200 perfumes in a few seconds (search fields only).

### Quick start

```json
{
  "searchQueries": ["vanilla"],
  "maxItems": 100
}
```

Highest rated women's perfumes launched since 2015 that contain Tonka Bean and have at least 500 votes:

```json
{
  "notes": ["Tonka Bean"],
  "gender": "female",
  "yearFrom": 2015,
  "minVotes": 500,
  "sortBy": "rating",
  "maxItems": 200
}
```

Every perfume of a brand, and single perfumes:

```json
{
  "startUrls": [
    "https://www.fragrantica.com/designers/Tom-Ford.html",
    "https://www.fragrantica.com/perfume/Maison-Francis-Kurkdjian/Baccarat-Rouge-540-33519.html"
  ],
  "maxItems": 0
}
```

### Input

| Field | What it does |
|---|---|
| `searchQueries` | Perfume names, brands or words, one per line. Each keyword is one search. |
| `brands` | Only these brands, as the site writes them (Dior, Tom Ford, Maison Francis Kurkdjian). |
| `gender` | Any, for women, for men or unisex. |
| `notes` | Only perfumes that have all these notes (Tonka Bean, Oud, Bergamot). |
| `olfactoryFamilies` | Only these families (Oriental Vanilla, Woody Aromatic, Floral Fruity). |
| `perfumers` | Only perfumes signed by these perfumers (Francis Kurkdjian, Alberto Morillas). |
| `yearFrom`, `yearTo` | Launch year range. |
| `minVotes` | Minimum number of rating votes. |
| `sortBy` | Most popular, highest rated, longest lasting or strongest sillage (the site's own orders). |
| `startUrls` | Perfume links, designer pages (every perfume of the brand) or search links from the site. |
| `includeDetails` | Note pyramid, accords, perfumers, family, description, similar perfumes (default on; opens each perfume page). |
| `maxItems` | Cap for the whole run (default 50; 0 = no cap). |
| `proxyConfiguration` | Apify Proxy by default. |

`searchQuery`, `keyword`, `query`, `brand`, `designers`, `ingredients`, `maxResults`, `urls` and `perfumeUrls` are
accepted too, so inputs written for other Fragrantica tools keep working.

### Output

One row per perfume (`type: perfume`):

| Field | What it is |
|---|---|
| `perfumeId`, `url` | Fragrantica perfume id and link |
| `name`, `brand`, `collection` | Perfume name, brand and the brand's collection (Private Blend...) |
| `year`, `gender` | Launch year; female, male or unisex |
| `rating`, `ratingCount`, `reviewsCount` | Average rating out of 5, rating votes and English reviews |
| `imageUrl` | Bottle image |
| `accords` | Main accords with their strength (`{"name": "woody", "strength": 100}`) |
| `mainAccords` | The same accords as a plain list, strongest first |
| `topNotes`, `middleNotes`, `baseNotes` | The note pyramid (empty when the perfume has a flat note list) |
| `notes` | Every note of the perfume (the pyramid in order, or the flat list) |
| `olfactoryFamily` | Family as the site classifies it (Oriental Woody, Aromatic Fougere...) |
| `perfumers` | Perfumers (noses) credited for the perfume |
| `description` | The site's description of the perfume |
| `alsoLike` | Perfumes that people who like this one also like (name, brand, link) |
| `sourceQuery` | Which keyword or link produced this row |

Fields from `accords` to `alsoLike` come with `includeDetails` on.

One real row (description and lists shortened):

```json
{
  "type": "perfume",
  "perfumeId": 1826,
  "name": "Oud Wood",
  "brand": "Tom Ford",
  "url": "https://www.fragrantica.com/perfume/Tom-Ford/Oud-Wood-1826.html",
  "year": 2007,
  "gender": "unisex",
  "collection": "Private Blend",
  "rating": 4.28,
  "ratingCount": 17775,
  "reviewsCount": 1879,
  "accords": [{"name": "woody", "strength": 100}, {"name": "warm spicy", "strength": 69}, {"name": "oud", "strength": 69}],
  "mainAccords": ["woody", "warm spicy", "oud", "aromatic", "vanilla", "balsamic", "fresh spicy", "amber"],
  "notes": ["Agarwood (Oud)", "Brazilian Rosewood", "Cardamom", "Sandalwood", "Sichuan Pepper", "Vanilla", "Vetiver", "Tonka Bean", "Amber"],
  "olfactoryFamily": "Oriental Woody",
  "perfumers": ["Richard Herpin"],
  "description": "Oud Wood by Tom Ford is a Oriental Woody fragrance for women and men. Oud Wood was launched in 2007...",
  "alsoLike": [{"name": "Noir Extreme", "brand": "Tom Ford", "url": "https://www.fragrantica.com/perfume/Tom-Ford/Noir-Extreme-29675.html"}]
}
```

### Errors you may see

Every error is a row with `errorCode` and is never charged:

| errorCode | Meaning |
|---|---|
| `INVALID_INPUT` | A field has a wrong value (for example an unknown gender or sort) |
| `INVALID_URL` | The link is not a Fragrantica perfume, designer or search link |
| `NOT_FOUND` | A perfume or designer that does not exist on Fragrantica |
| `NO_RESULTS` | No perfume for this keyword and filters (notes, families and perfumers must be spelled as on the site) |
| `NOT_REACHED` | The run timeout, the cost guard or `maxItems` arrived before this link |
| `BLOCKED` | The site refused every attempt; run it again in a few minutes |

### Integrations, scheduling and AI agents

- **Schedule** a brand or a note search weekly in [Apify schedules](https://docs.apify.com/platform/schedules) to
  catch new launches and follow how ratings and votes move.
- **Export** as JSON, CSV, Excel or XML, or read the dataset from the [Apify API](https://docs.apify.com/api/v2).
- **Connect** it to Make, n8n, Zapier or Google Sheets through
  [Apify integrations](https://docs.apify.com/platform/integrations), for example to enrich a shop catalog.
- **AI agents:** call it as a tool through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp)
  in Claude, ChatGPT, Cursor or any MCP client, for example "find unisex perfumes with oud and vanilla rated above 4
  with more than 1,000 votes and group them by family".

### FAQ

**Do I need a Fragrantica account?** No. The Actor uses the site's public search and public perfume pages.

**How many perfumes can I get?** The site search returns up to 1,000 perfumes per search. For a whole brand use its
designer page or the `brands` filter; to go past 1,000, split by gender, year range or note.

**Why is the note pyramid empty for some perfumes?** Many perfumes list their notes without top, middle and base
levels. Those have the full list in `notes` and empty pyramid fields.

**Why did my note filter return nothing?** Notes, families and perfumers must be written as the site shows them:
`Tonka Bean`, `Oriental Vanilla`, `Francis Kurkdjian`. Lowercase words are capitalized for you.

**Are longevity, sillage and season votes included?** No. The site does not publish those in a form that can be read
reliably, so they are left out rather than guessed.

**Is it legal?** The Actor reads public perfume data only. Perfumers appear only as the public name credited on the
perfume; no user, review author or member data is returned. You are responsible for how you use the data under the
laws that apply to you.

**Something broke or a field is missing?** Open an issue on the Actor page with the input you used; issues are
answered quickly.

### Limitations

- Up to 1,000 perfumes per search, a limit of the site's own search.
- Each perfume page is opened at a pace the site accepts, so runs with `includeDetails` take about 1 to 3 seconds per
  perfume.
- When the site refuses the default proxy, perfume pages may be skipped: rows then carry the search fields only.

### Changelog

- **16 Oct 2026**: first version. Keyword, brand, gender, note, family, perfumer, year and votes filters, four sort
  orders, perfume, designer and search links, note pyramid, accords with strength, perfumers and similar perfumes,
  free error rows.

# Actor input Schema

## `searchQueries` (type: `array`):

Perfume names, brands or words to search, one per line, for example vanilla, Baccarat Rouge or oud. Each keyword is one search. Can be left empty when you use the filters below.

## `brands` (type: `array`):

Only perfumes from these brands, as the site writes them, for example Dior, Tom Ford or Maison Francis Kurkdjian. Empty = all brands.

## `gender` (type: `string`):

Only perfumes for this gender, as Fragrantica classifies them.

## `notes` (type: `array`):

Only perfumes that have all these notes, for example Tonka Bean, Oud or Bergamot. Empty = any notes.

## `olfactoryFamilies` (type: `array`):

Only perfumes in one of these families, for example Oriental Vanilla, Woody Aromatic or Floral Fruity. Empty = any family.

## `perfumers` (type: `array`):

Only perfumes signed by one of these perfumers, for example Francis Kurkdjian or Alberto Morillas. Empty = any perfumer.

## `yearFrom` (type: `integer`):

Only perfumes launched in this year or later.

## `yearTo` (type: `integer`):

Only perfumes launched in this year or earlier.

## `minVotes` (type: `integer`):

Only perfumes with at least this many rating votes, for example 500 to skip obscure releases.

## `sortBy` (type: `string`):

Order of the results, the same orders the site offers in its search.

## `startUrls` (type: `array`):

Optional: Fragrantica perfume links (one row each), designer pages (every perfume of the brand) or search links copied from the site.

## `includeDetails` (type: `boolean`):

On: opens each perfume page for the note pyramid, accords with their strength, perfumers, family, description and similar perfumes. Off: much faster, only the search fields (name, brand, year, gender, rating, votes, reviews, image).

## `maxItems` (type: `integer`):

Hard cap for the whole run, across all searches. 0 = no cap (the site search returns up to 1,000 perfumes per search).

## `proxyConfiguration` (type: `object`):

Apify Proxy by default. Change it only if you know you need to. If the site refuses the proxy, rows may carry the search fields only.

## Actor input object example

```json
{
  "searchQueries": [
    "vanilla"
  ],
  "gender": "any",
  "sortBy": "popularity",
  "includeDetails": true,
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `resultsCsv` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "vanilla"
    ],
    "maxItems": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapewise/fragrantica-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQueries": ["vanilla"],
    "maxItems": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapewise/fragrantica-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "vanilla"
  ],
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapewise/fragrantica-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapewise/fragrantica-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/VqKg0pH6d2pi1hn7n/builds/TcwQ423tFgD4I5AIr/openapi.json
