# Lotte Duty Free Ranking Scraper — Korea Duty-Free Top 100 (`kdatafactory/lottedfs-scraper`) Actor

Scrape Lotte Duty Free (롯데면세점) Top-100 best-seller rankings, overall and across 14 categories: rank, brand, product, USD list price, discount rate, discounted price, the KRW the site shows, rating and reviews. Built on Lotte's own ranking endpoint.

- **URL**: https://apify.com/kdatafactory/lottedfs-scraper.md
- **Developed by:** [Seok June Park](https://apify.com/kdatafactory) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Lotte Duty Free Ranking Scraper — Korea Duty-Free Top 100

Scrape **Lotte Duty Free (롯데면세점)** — one of Korea's two dominant duty-free retailers — and get its **Top-100 best-seller ranking, overall and for 14 categories**, as clean JSON/CSV: rank, brand, product, USD list price, discount rate, discounted price, the KRW figure the board itself shows, rating and review count.

Built on the same ranking endpoint the kor.lottedfs.com storefront calls, so rows match what a shopper sees.

> **Why duty-free data?** Duty-free boards are where Korean beauty, liquor and luxury demand from international shoppers shows first — and prices swing with promotions daily. Track the Top 100 every day and you see both the demand ranking and the real discounted price curve.

### What you get

One row per ranked product:

| Field | Meaning |
|---|---|
| `ranking_category`, `rank` | Which board, and the product's position (1–100) |
| `name`, `brand` | Product and brand |
| `price_usd` | List price |
| `sale_price_usd`, `discount_rate` | Discounted price when Lotte shows it (see below) |
| `discount_hidden` | **`true` when Lotte hides the discount behind a login** for this product |
| `price_krw` | The KRW figure the board itself renders |
| `rating`, `review_count` | Review score (5-point scale) and count |
| `url`, `image_url`, `scraped_at` | Product link, image, KST timestamp |

#### The `discount_hidden` flag — read this

Lotte hides the discounted price of many products from logged-out visitors and shows **"로그인 후 할인율 확인"** instead. On a typical day that's **roughly a third of the board** (measured live: 505 of 1,500 rows). Those rows keep their real rank, list price and KRW figure, and carry `discount_hidden: true` with `sale_price_usd`/`discount_rate` null. That is Lotte's choice, not a scraping gap — the flag makes it explicit instead of papering over it.

#### What is deliberately NOT here

The final amount on Lotte's checkout (주문서) page also applies the **shopper's own member grade, coupons and L.POINT balance** — per-account values behind a login; no fixed "final price" exists on the site. This actor collects public data only: no login, no cart, no member or passport data.

### Categories

전체(all) · 주류(liquor) · 스킨케어(skincare) · 메이크업(makeup) · 향수/바디/헤어(fragrance) · 뷰티 디바이스(beautydevice) · 가방/지갑(bags) · 시계/주얼리(watches) · 아이웨어/잡화(eyewear) · 패션/슈즈(fashion) · 스포츠/레져(sports) · 건강/가공식품(food) · 디지털/가전(digital) · 리빙/헬스케어(living) · 키즈/베이비(kids)

Leave `categories` empty to scrape all 15 boards (1,500 rows).

### Input example

```json
{
  "categories": ["전체", "스킨케어"],
  "maxItemsPerCategory": 100
}
```

### Output example (real row)

```json
{
  "source": "lottedfs",
  "ranking_category": "전체",
  "rank": 1,
  "name": "LG PraL SP 써마샷 얼티밋",
  "brand": "LG프라엘",
  "price_usd": 364,
  "sale_price_usd": 287.74,
  "discount_rate": 21,
  "discount_hidden": false,
  "price_krw": 406002,
  "rating": 4.5,
  "review_count": 51,
  "url": "https://kor.lottedfs.com/kr/product/20001034326"
}
```

### Honest notes

- If a requested board returns nothing, the run **warns loudly** and records it in an `EMPTY_CATEGORIES` key-value record instead of exiting quietly.
- The run log summarises how many rows had their discount hidden, so a drop in coverage is visible immediately.
- No proxy needed for normal use; the board is served to ordinary IPs.

# Actor input Schema

## `categories` (type: `array`):

Which Top-100 boards to scrape. Leave empty for ALL of them. Korean name or English alias: 전체(all), 주류(liquor), 스킨케어(skincare), 메이크업(makeup), 향수/바디/헤어(fragrance), 뷰티 디바이스(beautydevice), 가방/지갑(bags), 시계/주얼리(watches), 아이웨어/잡화(eyewear), 패션/슈즈(fashion), 스포츠/레져(sports), 건강/가공식품(food), 디지털/가전(digital), 리빙/헬스케어(living), 키즈/베이비(kids).

## `maxItemsPerCategory` (type: `integer`):

How many ranked products to keep per board. Lotte publishes a Top 100, so 100 is the maximum and the default.

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

Optional. The ranking board is served to ordinary IPs, so a proxy is not required. Enable it only for high-volume schedules.

## Actor input object example

```json
{
  "categories": [
    "전체",
    "스킨케어"
  ],
  "maxItemsPerCategory": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

Every ranked product collected in this run.

# 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 = {
    "categories": [
        "전체"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kdatafactory/lottedfs-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 = { "categories": ["전체"] }

# Run the Actor and wait for it to finish
run = client.actor("kdatafactory/lottedfs-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 '{
  "categories": [
    "전체"
  ]
}' |
apify call kdatafactory/lottedfs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kdatafactory/lottedfs-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/MMdzGwwLivUKhdqT0/builds/3wviVq8aqoKYfFgEZ/openapi.json
