Fragrantica.com Scraper
Under maintenancePricing
from $2.99 / 1,000 results
Fragrantica.com Scraper
Under maintenanceScrape Fragrantica.com perfume data including fragrance names, brands, designers, notes, accords, ratings, reviews, release years, and product details. Ideal for perfume research, competitor analysis, fragrance discovery, market research, and product intelligence.
Pricing
from $2.99 / 1,000 results
Rating
0.0
(0)
Developer
SimpleAPI
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
2 days ago
Last modified
Categories
Share
Fragrantica Scraper — Perfume Notes, Accords, Ratings and Reviews
Fragrantica Scraper pulls structured perfume data straight from Fragrantica.com: the note pyramid, main accords, longevity and sillage breakouts, gender and season votes, aggregate ratings, pros/cons, and full user reviews. Give it perfume URLs, a free-text search query, or both, and each perfume comes back as one JSON record with over 40 fields — brand, launch year, accord colors, "reminds me of" recommendations and normalized review text included. Fragrance brands, retailers, market researchers, and recommendation-engine builders use it to turn Fragrantica's public catalogue into a dataset they can query, filter and join elsewhere. No Fragrantica account or login is required — everything returned is already visible to any anonymous visitor.
What is Fragrantica Scraper?
Fragrantica Scraper is an Apify Actor that turns a Fragrantica perfume page or search result into typed JSON. Point it at one or more perfume URLs, a search query, or a Fragrantica search-results link, and it returns every perfume it can reach as a dataset row — no Fragrantica account, cookie or login required, since every field it reads is already public on the page.
- Discovery by URL or query — paste exact perfume page links, a Fragrantica search URL (
?query=...), a free-textquery, or mix all three; results are de-duplicated and capped bymaxItems. - Deep structural fields — main accords with color/RGB, the full top/middle/base note pyramid, and longevity/sillage/price-value/rating breakouts with weighted averages.
- Community signal fields — aggregate rating, gender and season vote breakouts, pros & cons with like/dislike counts, and "people who like this also like" / "reminds me of" recommendations.
- Real user reviews — reviewer handle, publish date, comment text and per-review structured votes (rating, longevity, sillage, gender, season, relation), paginated up to your own cap.
- Configurable rendering — a Playwright browser renders Fragrantica's Vue.js sections by default; you can tune concurrency, request pacing and retry/backoff behavior.
- Live, partial-safe output — every perfume is pushed to the dataset the moment it finishes, so a crashed run still keeps everything scraped up to that point.
What data can I extract with Fragrantica Scraper?
Every perfume record carries four kinds of data: identity and media, composition (notes and accords), community sentiment (ratings, breakouts, reviews), and related-perfume signals.
| Field | Example value | Use case |
|---|---|---|
id | "5892" | Stable key for joins and de-duplication |
url | "https://www.fragrantica.com/perfume/Avon/Avon-Smile-5892.html" | Canonical link back to the source page |
title | "Avon Smile Avon perfume - a fragrance for women" | Raw page title, as published |
description | "Avon Smile by Avon is a Floral fragrance for women..." | Marketing copy for catalog listings |
primaryImageUrl | "https://fimgs.net/mdimg/perfume-thumbs/375x500.5892.jpg" | Hero product image |
images | ["https://fimgs.net/mdimg/...jpg"] | Full photo gallery |
brandName | "Avon" | Brand/designer facet |
brandUrl | "https://www.fragrantica.com/designers/Avon.html" | Link to the brand's catalogue page |
brandLogo | "https://fimgs.net/mdimg/dizajneri/m.7.jpg" | Brand logo image |
launchYear | 2010 | Release-year filtering and timeline analysis |
mainAccords | [{"accord":"floral","color":"Medium Purple","rgb":"rgb(169,119,188)","hex":"#a977bc","value":100}] | Scent-profile clustering |
pros | [{"label":"Bright fruity sweetness","like":3,"dislike":0,"score":6,"userVote":0}] | What wearers like, ranked by score |
cons | [{"label":"May not last long","like":1,"dislike":0,"score":2,"userVote":0}] | Common complaints, ranked by score |
pyramid | {"type":"full","topNotes":[...],"middleNotes":[...],"baseNotes":[...]} | Full note composition |
longevityBreakout | [{"very weak":77},{"weak":163},{"moderate":124},{"long lasting":28},{"eternal":14}] | Raw longevity vote counts |
longevityAverage | 2.3571 | Weighted longevity score |
longevitySum | 406 | Total longevity votes |
longevityMax | 163 | Largest single longevity bucket |
sillageBreakout | [{"intimate":164},{"moderate":192},{"strong":29},{"enormous":31}] | Raw sillage vote counts |
sillageAverage | 1.8245 | Weighted sillage score |
sillageSum | 416 | Total sillage votes |
sillageMax | 192 | Largest single sillage bucket |
priceValueBreakout | [{"way overpriced":3},{"overpriced":5},{"ok":28},{"good value":61},{"great value":62}] | Raw price-value vote counts |
priceValueAverage | 4.0943 | Weighted price-value score |
priceValueSum | 159 | Total price-value votes |
priceValueMax | 62 | Largest single price-value bucket |
perfumeRating | 3.55 | Fragrantica's published aggregate rating |
ratingBreakout | [{"hate":7},{"dislike":286},{"ok":45},{"like":553},{"love":166}] | Raw love/like/ok/dislike/hate vote counts |
ratingAverage | 3.5535 | Weighted rating score from the breakout |
ratingSum | 1057 | Real vote total from the breakout |
ratingMax | 553 | Largest single rating bucket |
bestRating | 5 | Rating scale ceiling |
ratingCount | 1057 | Fragrantica's own published vote total |
reviewCount | 91 | Reviews collected in this run |
gender | "female" | Gender facet, parsed from the title |
genderBreakout | {"female":150,"femaleUnisex":5,"unisex":1,"male":0,"maleUnisex":0} | Gender vote distribution |
genderSum | 156 | Total gender votes |
genderMax | 150 | Largest gender vote bucket |
thisPerfumeRemindsMeOf | [{"id":56433,"title":"Barbie Pink Kiss","brand":"Avon","gender":null,"url":"...","image":"..."}] | Similar-scent recommendations |
seasonBreakout | {"winter":161,"spring":309,"summer":268,"autumn":133,"day":451,"night":101} | Seasonal/time-of-day fit |
relationBreakout | {"have":698,"had":1275,"want":228} | Ownership-intent signal |
relationSum | 2201 | Total relation votes |
relationMax | 1275 | Largest relation vote bucket |
perfumers | ["Cecile Matton","Julie Masse"] | Nose/perfumer credits |
peopleWhoLikeThisAlsoLike | [{"url":"...","brand":"Avon","title":"Far Away Avon","image":"..."}] | Cross-sell recommendations |
reviews | [{"name":"itsmaria","published":"2025-09-24","comment":"...","votes":{...}}] | Full review text and structured votes |
Ratings, breakouts and reviews
The decision-driving fields sit in two independently-sourced places. perfumeRating, bestRating and ratingCount come from Fragrantica's own published schema.org/AggregateRating markup on the page. ratingBreakout, ratingSum, ratingMax and ratingAverage come from the site's separate love/like/ok/dislike/hate vote widget — ratingSum is the real vote total added up from that breakout, not a copy of ratingCount, so the two numbers can legitimately differ. longevityBreakout, sillageBreakout and priceValueBreakout follow the same pattern: raw counts plus a weighted average and the largest bucket. reviews carries the actual review text, publish date and each reviewer's own structured votes, capped per perfume by maxItemsReviews.
Composition and targeting fields
mainAccords and pyramid describe what the perfume actually smells like — accords carry a named color, RGB and intensity value; the pyramid splits top/middle/base notes (or a single flat list when Fragrantica doesn't split levels). brandName, gender, launchYear and genderBreakout/seasonBreakout are the fields you filter and segment a catalogue on — by designer, by target gender, by decade, or by which season a fragrance actually gets worn in, according to Fragrantica's own community votes.
Why not build this yourself?
Fragrantica has no public API for bulk catalogue or review access, so the alternative to an Actor is a DIY scraper — and the site is actively hostile to one. Fragrantica's current frontend hydrates every perfume page with Vue.js, which destroys the server-rendered markup a regex- or selector-based parser needs (the note pyramid, review cards and accord bars are custom elements that only exist before hydration finishes). A DIY scraper has to either freeze the page before Vue mounts, or reverse-engineer the same raw-HTML re-fetch trick this Actor uses internally.
The second cost is access. Fragrantica's edge frequently hard-blocks plain HTTP clients with a Cloudflare challenge, so reliable fetching needs browser-accurate TLS fingerprinting, a sticky proxy escalation ladder (direct → datacenter → residential), and a shared rate-limit cooldown so concurrent workers don't pile into the same block. None of that is a one-off script — it is infrastructure you maintain indefinitely as Fragrantica's anti-bot posture changes.
There is also no stable search endpoint to call directly: Fragrantica's own site search runs through a secured Algolia key embedded in its homepage HTML, which expires and is rotated. Building your own search means re-harvesting and validating that key on every run — this Actor already does it, falling back safely rather than searching against a dead key.
A one-off manual lookup on Fragrantica's own site is fine for checking a single perfume. Fragrantica Scraper is for anything beyond that: bulk catalogue pulls, scheduled monitoring, or feeding perfume data into another system as structured JSON.
How to use data extracted from Fragrantica Scraper
Open Fragrantica Scraper in the Apify Console, paste perfume URLs or a search query into the input, adjust maxItems if needed, and click Start — no proxy or extra setup is required for a first run. Results land in your dataset live, exportable as JSON, CSV, Excel or XML.
Fragrance brands and product teams
A brand team auditing its own catalogue pastes its perfume URLs into startUrls and pulls mainAccords, pyramid, longevityBreakout and perfumeRating for every release, then compares the community's longevity/sillage perception against the brand's own marketing claims. pros and cons surface the exact wording customers use — useful raw material for product copy and FAQ pages.
Retailers and price-comparison platforms
A retailer building a fragrance catalogue page runs a query search per brand or scent family, capturing title, brandName, primaryImageUrl, mainAccords and perfumeRating to populate product listings, refreshing on a schedule so ratings and review counts stay current without manual re-entry.
Market research and competitive intelligence
An analyst tracking a fragrance category pulls genderBreakout, seasonBreakout and relationBreakout across every perfume in a brand's line to map who actually wears it, when, and how many people say they own it versus merely want it — segment sizing a spreadsheet alone can't produce from Fragrantica's page views.
AI agents and recommendation pipelines
An AI engineer builds a fragrance-recommendation agent by indexing mainAccords, pyramid and description per perfume into a vector store, then uses peopleWhoLikeThisAlsoLike and thisPerfumeRemindsMeOf as ready-made candidate lists an agent can re-rank against a user's stated preferences — no need to compute scent similarity from scratch.
⬇️ Input
None of the parameters are required — provide startUrls, query, or both. Descriptions below are reproduced exactly from the input schema.
| Parameter | Type | Default | Constraints | Description |
|---|---|---|---|---|
startUrls | array | [] | list of strings | List one or more Fragrantica perfume URLs (e.g. https://www.fragrantica.com/perfume/Avon/Avon-Smile-5892.html) or search URLs (e.g. https://www.fragrantica.com/search/?query=Avon). |
query | string | "" | free text | Free-text search query for Fragrantica. Used when no startUrls are given, or to top-up results to reach maxItems. |
maxItems | integer | 10 | min 1, max 10000 | Hard cap on perfumes to scrape across all inputs. |
allReviews | boolean | true | — | If enabled, the actor will scroll and paginate through reviews on each perfume page. |
maxItemsReviews | integer | 5 | min 0, max 10000 | Cap reviews collected per perfume page. |
omitFields | array | [] | list of strings | Optional list of top-level fields to drop from each output item. |
proxyConfiguration | object | {"useApifyProxy": false} | Apify Proxy editor | Use Apify Proxy or your own proxy URLs. Leave disabled for the built-in direct → datacenter → residential fallback. |
useBrowser | boolean | true | — | Use Playwright/Chromium to render the Vue.js sections (note pyramid, longevity/sillage/season/gender breakouts, pros & cons, reviews, 'reminds me of'). Turn OFF for a faster static-only scrape that returns just the server-rendered fields (accords, brand, rating, description, images). |
browserHeadless | boolean | true | — | Run Chromium in headless mode. Leave enabled unless you are debugging rendering. |
blockHeavyResources | boolean | true | — | Block ads, trackers, fonts and media during browser rendering for faster, lighter page loads. Recommended. |
concurrency | integer | 2 | min 1, max 10 | How many perfume pages to fetch/enrich in parallel. Higher is faster but more likely to trigger rate limits. |
minRequestIntervalSeconds | number | 1.5 | min 0, max 60 | Floor delay enforced between outgoing requests to stay polite and avoid blocks. |
requestJitterSeconds | number | 0.8 | min 0, max 30 | Extra random delay (0…N s) added on top of the minimum interval to look less robotic. |
requestTimeoutSeconds | integer | 30 | min 5, max 180 | Abort a single HTTP request if it takes longer than this. |
maxRetries | integer | 5 | min 0, max 20 | How many times to retry a blocked/failed perfume fetch (escalating the proxy tier) before giving up on that URL. |
retryBackoffSeconds | integer | 4 | min 0, max 60 | Base seconds for the exponential backoff between retries. |
rateLimitCooldownSeconds | integer | 30 | min 0, max 300 | When a 429/503 is seen, all workers pause for at least this many seconds to prevent a retry storm. |
logLevel | string (enum) | "INFO" | DEBUG, INFO, WARNING, ERROR | Logging level for the run. |
debugDumpHtml | boolean | false | — | Save the rendered page HTML to the key-value store for troubleshooting a parsing issue. Leave off for normal runs. |
Example input
{"startUrls": [{ "url": "https://www.fragrantica.com/perfume/Avon/Avon-Smile-5892.html" }],"query": "oud","maxItems": 50,"allReviews": true,"maxItemsReviews": 20,"omitFields": [],"proxyConfiguration": { "useApifyProxy": false },"concurrency": 2}
Common pitfall: only exact perfume detail pages (/perfume/<brand>/<name>-<id>.html) and Fragrantica search URLs that carry a ?query= parameter are accepted in startUrls. A brand/designer catalogue page (e.g. /designers/Zara.html) matches neither pattern and is skipped with a "Skipping unsupported startUrl" log line rather than being scraped — use the query field instead to pull a whole brand's catalogue by name.
⬆️ Output
Each dataset item is one perfume as flat, typed JSON — the same field set on every run, values omitted (not renamed) when omitFields is used. pyramid, mainAccords, pros, cons, and every *Breakout/reviews field require useBrowser (on by default) since they come from Fragrantica's Vue.js-rendered sections.
{"id": "5892","url": "https://www.fragrantica.com/perfume/Avon/Avon-Smile-5892.html","title": "Avon Smile Avon perfume - a fragrance for women","description": "Avon Smile by Avon is a Floral fragrance for women. The fragrance features Mandarin Orange, Freesia and Mimosa.","primaryImageUrl": "https://fimgs.net/mdimg/perfume-thumbs/375x500.5892.jpg","images": ["https://fimgs.net/mdimg/perfume-social-cards/en-p_c_5892.jpeg","https://fimgs.net/mdimg/secundar/o.5892.jpg"],"brandName": "Avon","brandUrl": "https://www.fragrantica.com/designers/Avon.html","brandLogo": "https://fimgs.net/mdimg/dizajneri/m.7.jpg","launchYear": 2010,"mainAccords": [{ "accord": "floral", "color": "Medium Purple", "rgb": "rgb(169, 119, 188)", "hex": "#a977bc", "value": 100.0 },{ "accord": "citrus", "color": null, "rgb": "rgb(249, 255, 82)", "hex": "#f9ff52", "value": 62.4 }],"pros": [{ "label": "Bright fruity sweetness", "like": 3, "dislike": 0, "score": 6, "userVote": 0 }],"cons": [{ "label": "May not last long, generous application needed", "like": 1, "dislike": 0, "score": 2, "userVote": 0 }],"pyramid": {"type": "full","topNotes": [{ "name": "Mandarin Orange", "img": "https://fimgs.net/mdimg/sastojci/t.12.jpg", "url": "https://www.fragrantica.com/notes/Mandarin-Orange-12.html" }],"middleNotes": [{ "name": "Freesia", "img": "https://fimgs.net/mdimg/sastojci/t.94.jpg", "url": "https://www.fragrantica.com/notes/Freesia-94.html" }],"baseNotes": [{ "name": "Mimosa", "img": "https://fimgs.net/mdimg/sastojci/t.55.jpg", "url": "https://www.fragrantica.com/notes/Mimosa-55.html" }]},"longevityBreakout": [{ "very weak": 3 }, { "weak": 12 }, { "moderate": 6 }, { "long lasting": 2 }, { "eternal": 0 }],"longevityAverage": 2.3043,"longevitySum": 23,"longevityMax": 12,"sillageBreakout": [{ "intimate": 9 }, { "moderate": 8 }, { "strong": 2 }, { "enormous": 0 }],"sillageAverage": 1.6316,"sillageSum": 19,"sillageMax": 9,"priceValueBreakout": [{ "way overpriced": 1 }, { "overpriced": 2 }, { "ok": 5 }, { "good value": 8 }, { "great value": 4 }],"priceValueAverage": 3.55,"priceValueSum": 20,"priceValueMax": 8,"perfumeRating": 3.4,"ratingBreakout": [{ "hate": 1 }, { "dislike": 4 }, { "ok": 3 }, { "like": 12 }, { "love": 5 }],"ratingAverage": 3.44,"ratingSum": 25,"ratingMax": 12,"bestRating": 5,"ratingCount": 25,"reviewCount": 20,"gender": "female","genderBreakout": { "female": 18, "femaleUnisex": 2, "unisex": 4, "maleUnisex": 0, "male": 1 },"genderSum": 25,"genderMax": 18,"thisPerfumeRemindsMeOf": [{ "id": 56433, "title": "Barbie Pink Kiss", "brand": "Avon", "gender": null, "url": "https://www.fragrantica.com/perfume/Avon/Barbie-Pink-Kiss-56433.html", "image": "https://fimgs.net/mdimg/perfume/s.56433.jpg" }],"seasonBreakout": { "winter": 4, "spring": 16, "summer": 12, "autumn": 3, "day": 21, "night": 5 },"relationBreakout": { "have": 5, "had": 3, "want": 7 },"relationSum": 15,"relationMax": 7,"perfumers": ["Cecile Matton", "Julie Masse"],"peopleWhoLikeThisAlsoLike": [{ "url": "https://www.fragrantica.com/perfume/Avon/Far-Away-4908.html", "brand": "Avon", "title": "Far Away Avon", "image": "https://fimgs.net/mdimg/perfume-thumbs/s.4908.jpg" }],"reviews": [{"name": "itsmaria","published": "2025-09-24","comment": "Simple and has a youthful aroma. Not bad, quite nice. If you don't like heavy sweet perfumes, this isn't for you.","votes": {"rating": 4, "winter": 0, "spring": 0, "summer": 0, "autumn": 0, "day": 1, "night": 0,"longevity": 2, "sillage": 1, "gender": "female", "relation": "have"}}]}
How do you filter and target specific perfumes?
Getting the right subset out of Fragrantica comes down to three decisions: how you find perfumes, what you narrow the results to before scraping, and how much data you pull per perfume.
Direct URLs vs. search query. If you already know exactly which perfumes you want, paste their pages into startUrls — this is the most reliable path since it never touches Fragrantica's search index. Use query when you want to discover perfumes by keyword (a brand name, a note, a scent family); query runs against Fragrantica's Algolia-powered search and results top up whatever startUrls didn't already provide, up to maxItems.
Scope by brand or note. There is no dedicated category/location filter — scope comes from the query text itself (a brand name, note, or accord word) or from a Fragrantica search URL you've already narrowed in your browser before pasting it in.
Volume controls. maxItems caps total perfumes across every input combined, not per-URL. maxItemsReviews caps reviews per perfume independently — set it to 0 to skip review pagination and speed up broad catalogue pulls, or raise it when reviews are the point of the run.
{ "startUrls": [{ "url": "https://www.fragrantica.com/perfume/Dior/Sauvage-31861.html" }], "allReviews": true, "maxItemsReviews": 100 }
{ "query": "vanilla oud", "maxItems": 100, "allReviews": false }
{ "query": "Chanel", "maxItems": 500, "maxItemsReviews": 0, "omitFields": ["reviews", "images"] }
How to extract Fragrantica data programmatically
Fragrantica Scraper runs on Apify, so any language that can call the Apify API can run it — the Console, the apify_client SDK, a schedule, or a webhook all use the same input shape shown above.
Python example
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("<YOUR_USERNAME>/fragrantica-com-scraper").call(run_input={"startUrls": [{"url": "https://www.fragrantica.com/perfume/Avon/Avon-Smile-5892.html"}],"query": "oud","maxItems": 50,"allReviews": True,"maxItemsReviews": 20,})for perfume in client.dataset(run["defaultDatasetId"]).iterate_items():print(perfume["title"], perfume["brandName"], perfume["perfumeRating"], perfume["longevityAverage"])
Export to spreadsheets or CRM
Download the dataset as CSV or Excel directly from the Console, or pull it via the API. Map title → Product Name, brandName → Brand, perfumeRating → Rating, launchYear → Release Year, and mainAccords/reviews → separate detail sheets, since both are nested arrays that don't flatten cleanly into a single spreadsheet column.
How does Fragrantica Scraper handle rate limits and blocking?
Every run starts with a direct connection — no proxy at all. Fragrantica often accepts a direct request from the Actor's Chrome-impersonating HTTP client, so skipping the proxy makes the first batch of a run faster and cheaper. Only once a request comes back blocked does the Actor react.
Blocking is detected two ways: an HTTP status of 403, 429 or 503, or a 200 response whose body still carries a Cloudflare interstitial (Fragrantica's "just a moment" / cf_chl challenge markup). Either one triggers proxy_manager.escalate(): the Actor moves from direct to an Apify datacenter proxy, and if that also fails, to residential, retrying up to 3 times on residential before it gives up on that tier. Once a fallback engages, the run sticks with that tier for every remaining request — it never drops back down to a cheaper tier mid-run, and it never flaps between tiers. If you explicitly set proxyConfiguration yourself (for example, forcing residential), that choice is honored outright and automatic escalation is skipped entirely.
Underneath the proxy ladder, minRequestIntervalSeconds plus requestJitterSeconds space out every outgoing request so traffic doesn't look robotic. When a 429/503 is actually seen, rateLimitCooldownSeconds sets a shared cooldown gate — every concurrent worker (up to your concurrency setting) waits out that same gate before firing again, which is what stops a burst of parallel workers from retrying straight into the same block. Each failed fetch is retried up to maxRetries times with exponential backoff seeded by retryBackoffSeconds, honoring a Retry-After response header when Fragrantica sends one.
When useBrowser is on (the default), a blocked static fetch doesn't fail the perfume outright — the Actor falls back to fetching the same page through Playwright's Chromium, which carries the Cloudflare clearance cookie the browser navigation just earned. That fallback is what makes the default configuration materially more resilient than the static-only mode described below.
⚠️ Known limitations
reviewCountreflects this run, not Fragrantica's true total. It counts the reviews actually collected (bounded bymaxItemsReviews), not the site's full review archive for that perfume.- Turning
useBrowseroff trades resilience for speed. It is documented as a faster static-only mode, but Fragrantica's current frontend frequently blocks plain HTTP requests with a Cloudflare challenge — the browser is also this Actor's fallback path when that happens. WithuseBrowseroff, a blocked static fetch has nowhere left to fall back to and that perfume fails outright. - Only exact perfume pages and
?query=search URLs are accepted asstartUrls. Brand/designer catalogue pages are not a supported input; use thequeryfield to pull an entire brand. - Search depends on a freshly harvested Algolia key. The Actor re-harvests a secured search key from the Fragrantica homepage at the start of every run (a key baked into an earlier version expired 2026-05-25). If that harvest ever fails, search falls back to the expired key and simply returns zero hits for
queryrather than failing the run — check the run log for "Harvested a fresh Algolia key" to confirm search is live. - Accord colors are looked up, not guaranteed.
rgbandhexare always present on amainAccordsentry;coloris a friendly name from a fixed palette and comes backnullfor a hex value outside that palette.
Is it legal to scrape Fragrantica.com?
Scraping publicly available Fragrantica pages for perfume and community data is generally permissible, since Fragrantica Scraper only collects what any anonymous visitor already sees on the page — no login, account or paywall is bypassed.
Perfume catalogue fields (accords, notes, brand, launch year, ratings) are product and business data, not personal data, so the obligations that apply are Fragrantica's terms of service and ordinary database-rights rules around systematic reuse of a compiled catalogue — GDPR does not attach to that part of the output. reviews, however, carries reviewer handles and free-text comments — public user-generated content that can still count as personal data under GDPR/CCPA if you store and reuse it at scale. Consult legal counsel before bulk-storing or republishing reviewer-identifiable review data commercially.
❓ Frequently asked questions
Can I get user reviews along with perfume data?
Yes. Set allReviews: true (the default) and maxItemsReviews to your cap. Each review returns the reviewer's handle, publish date, comment text, and their individual structured votes (rating, longevity, sillage, gender, season, relation). Set maxItemsReviews: 0 to skip reviews entirely and speed up the run.
How many perfumes can I get per run?
maxItems accepts 1 to 10,000, as a total across every startUrls entry and your query combined — it is not a per-URL or per-query figure.
What happens if a perfume page is blocked or can't be fetched?
The Actor retries with escalating proxy tiers (direct → datacenter → residential) up to maxRetries times. If every attempt still fails, that URL is logged as a failure and skipped — it is never pushed to the dataset, so you are not charged for it.
Why did my search query return zero perfumes?
Most often either the query genuinely has no matches, or the Actor's homepage-harvested Algolia search key failed to refresh for that run (search then returns zero hits rather than erroring the run — see Known Limitations above). Pasting known perfume URLs directly into startUrls sidesteps this entirely.
Should I paste direct perfume URLs or use a search query?
Use startUrls whenever you already know the perfumes you want — it's the more reliable path since it never touches Fragrantica's search index. Use query for discovery by brand, note or scent family.
How accurate is the rating and review data? The Actor returns the ratings, breakouts and reviews exactly as they appear on the page at request time. Accuracy depends on how recently Fragrantica's community has updated those votes; re-run periodically if you need current numbers.
Does Fragrantica Scraper work with Claude, ChatGPT and other AI agent frameworks? Yes. It is callable as a standard HTTP endpoint through the Apify API, so any agent framework that can make a request — LangChain, CrewAI, a custom tool definition — can invoke it and get typed JSON back.
How does Fragrantica Scraper compare to other Fragrantica scrapers?
Checked on the Apify Store on 26 July 2026: lexis-solutions/fragrantica returns a similar 40+ field structure but does not emit launchYear and sets ratingSum equal to ratingCount rather than the real vote total from the rating breakout. shahidirfan/fragrantica-com-scraper scrapes designer/brand catalogue pages instead of individual perfumes, returning flattened locale fields (url_en, reviews_en) and popularity scores rather than notes, accords or reviews. scrapier/fragrantica-com-scraper covers a comparable field set with a Pay-Per-Event result-item charge. This Actor's difference is launchYear sourced from Fragrantica's search index, an honest ratingSum/ratingAverage computed from the real vote breakout, and per-review structured votes rather than review text alone.
Can I use Fragrantica Scraper without a Fragrantica account or API key? Yes. No Fragrantica login, cookie or API key is needed — the Actor reads only public pages. The one credential required is your own Apify token to run the Actor.
🔗 Want to try other review and ratings scrapers?
| Scraper | What it extracts |
|---|---|
| Apple App Store Review Scraper | Public App Store reviews — star rating, review text, app version, reviewer and publish date |
| Google Play Store Review Scraper & Developer Replies | Play Store reviews plus the developer reply attached to each one, with reply-rate summaries |
| Goodreads Review Scraper By Star Rating & Spoiler Filter | Goodreads book reviews filtered by star range, spoiler flag, minimum likes and comment count |
Conclusion
Fragrantica Scraper turns Fragrantica's perfume pages and search results into structured, typed JSON — notes, accords, ratings, breakouts and full reviews included, with a schema that stays stable across runs. It's built for brands auditing their own catalogue, retailers populating product listings, researchers segmenting a fragrance category, and AI agents that need scent data without scraping HTML themselves. Open Fragrantica Scraper in the Apify Console, paste a perfume URL or a search term, and start pulling data.
💬 Your feedback
Found a bug, or need a field that's on the page but missing from the output? Open an issue on the Actor's Issues tab on Apify — a sample perfume URL and the run ID make it fastest to fix.