flaconi Scraper - Perfume & Beauty Price Watch (Germany) avatar

flaconi Scraper - Perfume & Beauty Price Watch (Germany)

Pricing

from $2.10 / 1,000 product scrapeds

Go to Apify Store
flaconi Scraper - Perfume & Beauty Price Watch (Germany)

flaconi Scraper - Perfume & Beauty Price Watch (Germany)

flaconi scraper: flaconi.de category listings (perfume, skincare, make-up, hair) to one row per product size with price in EUR, UVP and percent off, 30-day lowest price, price per litre, brand, EAN, badges and fragrance notes. For German beauty price and discount watching.

Pricing

from $2.10 / 1,000 product scrapeds

Rating

0.0

(0)

Developer

Superslow Sloth

Superslow Sloth

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Security

Limited permissions

Share

flaconi scraper: perfume and cosmetics price and discount watch (Germany)

This flaconi scraper reads the category pages of flaconi.de (perfume, skincare, make-up, hair, body, sale) and returns one flat row per product size: the price in EUR, the struck-through UVP (recommended retail price) and the percent off, the lowest price of the last 30 days, the price per litre or per piece, brand, product line, EAN barcode, badges (Neu, Limitiert, + Geschenk), voucher code and fragrance notes. Run it on a schedule and diff the dataset to get a German beauty price and discount watch: which Dior, Chanel, Gucci or Jean Paul Gaultier perfume dropped, which products sit 40% under the UVP, and what is new.

No account, no API key, no login, no browser. One request returns about 50 products.

Input

FieldNotes
categoriesOne or more flaconi categories, one per line: the slug from the page address (parfum, damenparfum, make-up, sale) or the page URL (https://www.flaconi.de/kategorie/parfum/). Only /kategorie/<slug>/ listings are supported, not brand pages, search or product pages. A slug flaconi does not know fails with a message and costs nothing.
maxItemsProducts to read per category (default 100, up to 1,000). About 50 a page. flaconi serves about 1,000 products per category however many pages its pager claims, so 1,000 is the most a category yields.
proxyConfigurationApify RESIDENTIAL proxy by default. flaconi.de sits behind Cloudflare, which refuses most datacenter addresses.

Example input:

{
"categories": ["parfum", "damenparfum", "https://www.flaconi.de/kategorie/sale/"],
"maxItems": 100
}

Output

Prices are numbers in euros, gross, as the shop shows them; currency is EUR. One row is one size (variant) of a product: flaconi sells a perfume in several sizes under one product page and the grid shows one size per tile, so a page can appear as several rows. product_id is the unique key within a category.

FieldNotes
category, position, pageThe category slug the row was read from, the place in that category's own list counting from 1 across pages (taken before repeats are dropped), and the 1-based page. flaconi's default order drifts between requests.
product_id, config_id, eanThe size's SKU (80062316-60), the product's SKU shared by its sizes (80062316-C), and the EAN-13 barcode. ean is null on sponsored tiles, which the page does not list in its structured data.
name, brand, line, product_typeThe name as the tile prints it (DIOR Sauvage Elixir Parfum), and its parts: brand DIOR, line Sauvage Elixir, type Parfum (Eau de Parfum, Duftset, Haarserum...).
url, image_urlThe product link with ?variant=<product_id> (opens that size) and the tile photo. image_url is null for a tile with a placeholder (7 of 1,000 parfum rows).
price, price_fromThe price now for the size in size. price_from is true when the tile prints "ab" ("from"): flaconi has other sizes of the product and this is the cheapest price the tile stands for; size and base_price stay those of the tile's variant.
original_price, on_sale, discount_percentThe "UVP" (unverbindliche Preisempfehlung) the tile strikes through, whether it is above price, and (1 - price / original_price) * 100 to one decimal. Null when the tile shows no UVP. The UVP is the manufacturer's recommended price, not a price history. The tile prints "(-31%)" on only some discounted tiles (194 of 233 measured); the printed integer matched the computed figure within one point every time, so the column is computed for all of them.
lowest_price_30dThe lowest price of the last 30 days, the figure EU law makes the shop disclose beside a reduction ("Niedrigster Preis in den letzten 30 Tagen"), from the search record the page embeds. Null when flaconi sends none (208 of 2,000 rows on sale and damenparfum). It can be above price (73 of 1,792): on an "ab" tile it belongs to the product's headline price, not necessarily the size's.
voucher_codeThe code of a campaign the tile advertises as a badge (the badge CALVINKLEIN is the code CALVINKLEIN). price does not include the voucher's saving. Null when there is no campaign (56 of 2,000 rows had one).
size, base_price, base_unitThe size the tile prices (60 ml, 3 Stk), the price per base unit the tile prints (1.853,50 € / 1 l gives 1853.5) and the unit (1 l, 1 Stk, 1 kg).
badges, sponsoredThe badge texts on the tile (Neu, Limitiert, + Geschenk, + Try me, Exklusiv, a campaign code); empty list when none. sponsored is true on a tile flaconi marks "Gesponsert" (a paid placement; 47 of the first 1,000 parfum rows).
top_notes, heart_notes, base_notesFragrance notes as flaconi writes them (Kopfnoten, Herznoten, Basisnoten). Null for a non-fragrance product, a product with none listed, and sponsored tiles.
currencyEUR.

Example row (real values, 2026-11-05, parfum category):

{
"category": "parfum",
"position": 1,
"page": 1,
"product_id": "80062316-60",
"config_id": "80062316-C",
"ean": "3348901567572",
"name": "DIOR Sauvage Elixir Parfum",
"brand": "DIOR",
"line": "Sauvage Elixir",
"product_type": "Parfum",
"url": "https://www.flaconi.de/parfum/dior/sauvage/dior-sauvage-elixir-parfum.html?variant=80062316-60",
"image_url": "https://cdn.flaconi.net/media/catalog/product/3/3/3348901567572-1_c_live.jpg?r=1WAIEA&c=de",
"currency": "EUR",
"price": 111.21,
"price_from": true,
"original_price": 184.0,
"on_sale": true,
"discount_percent": 39.6,
"lowest_price_30d": 111.21,
"voucher_code": null,
"size": "60 ml",
"base_price": 1853.5,
"base_unit": "1 l",
"badges": [],
"sponsored": false,
"top_notes": "Grapefruit",
"heart_notes": "Lavendel",
"base_notes": null
}

Honest nulls, and what the listing does not carry

A field the tile did not show is null, never 0 or ""; badges is an empty list when there are none.

  • No rating or review count. The category grid prints neither.
  • No stock column. All 365 search records measured on 2026-11-05 said in stock, and no tile showed an out-of-stock state, so there is nothing to report.
  • A price is not a price history. original_price is the manufacturer's UVP and lowest_price_30d covers 30 days. Keep your own history by running on a schedule.
  • Other sizes. An "ab" tile (price_from true) stands for several sizes; the others appear as their own rows only if the category lists them as their own tiles.
  • Repeats. Consecutive pages share 4 to 5 products and the same product can appear on two pages; a product_id is returned and charged once per category. Reading 1,000 parfum products took 21 pages and skipped 128 repeated tiles.

Pricing

Pay per event:

  • $0.002 per run (actor-start), charged only after your input is validated, so a run that fails on bad input costs nothing.
  • $0.0021 per product written (product-scraped), i.e. $2.10 per 1,000 products. A row that is not written is not charged: repeats of a product the same category already returned, and a category that fails, are free.

How it fetches

flaconi.de is a server-rendered Next.js shop behind Cloudflare. A category page (https://www.flaconi.de/kategorie/parfum/) is about 1.7 MB of HTML holding 45 to 55 product tiles, a schema.org list of the non-sponsored ones (EAN, fragrance notes) and the search records the page embeds (30-day lowest price, voucher). This actor reads that page with a browser's TLS fingerprint through Apify's RESIDENTIAL proxy and rotates the exit address on every refused attempt. A plain HTTP client is answered 403 ("Just a moment...").

Things worth knowing, all measured on 2026-11-05:

  • Paging is zero-based ?page=. The bare address is page 0; ?page=1 is the second page. ?p=, ?seite= and ?pageNumber= are ignored.
  • Depth is about 1,000 products a category, not what the pager says. parfum claims 124 pages; the last page with tiles is ?page=20 (21 pages) and ?page=21 answers HTTP 200 with flaconi's "no products found" message, which the actor reads as the end. A short category stops on its pager (duftoel: 2 pages, 79 products).
  • An unknown slug is HTTP 404 and fails that category with a message; the other categories still run.
  • Weight. About 1.7 MB and 2 to 3 seconds a page from the build machine, so a 30-product run is one request and a 1,000-product category is 21.
  • Proxy. A probe from the Apify platform read the category page through datacenter addresses 3 of 10 times (HTTP 403 the other seven) and through RESIDENTIAL ones 10 of 10, so RESIDENTIAL is the default and the log warns when it is not selected.

If flaconi changes the page, the run fails with a message instead of returning empty rows.