# 29CM Scraper — Korean Designer Fashion & Lifestyle Products (`kdatafactory/29cm-scraper`) Actor

Scrape 29CM, Korea's premium designer-curation store: keyword search and category rankings with brand, KRW price, sale price, discount rate, rating, review count and images as clean JSON. Built on 29CM's own product API. For K-fashion trend research, price monitoring, and product sourcing.

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

## Pricing

from $2.50 / 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/platform/actors/running/actors-in-store#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

## 29CM Product Scraper 🛍️

Scrape **searched** and **category-ranked** products from [29CM](https://www.29cm.co.kr) — Korea's premium designer-curation store for fashion, beauty, and lifestyle — as clean, structured JSON. Get product names, brands, KRW prices, discounts, ratings, review counts, "heart" (wishlist) counts, and images in one call.

Built for **K-fashion & lifestyle trend research**, **dropshipping product sourcing**, and **price monitoring**.

> **Try it free.** Apify's free plan includes $5 of monthly platform credit — roughly **2,000 results** from this actor, no credit card required. Set your input, click Start, and export JSON/CSV/Excel.

***

### What it does

This actor pulls product data directly from 29CM's public product API (the same one that powers 29cm.co.kr), so results are fast and complete — no fragile HTML scraping in the happy path. Two modes:

- **Search** — every product matching a keyword (e.g. `nike`, `coat`, `가디건`). Deep, reliable pagination.
- **Category ranking** — the best-selling products for a 29CM large-category code. When sorted by `BEST`, each item includes its `rank`.

If the JSON API is ever unavailable, the actor automatically falls back to extracting the product list from the search page's embedded `__NEXT_DATA__` payload.

***

### Input

| Field | Type | Description |
|-------|------|-------------|
| `mode` | string | `"search"` or `"category"`. |
| `query` | string | **Search mode:** a keyword. **Category mode:** a 29CM large-category code (see below). |
| `sort` | string | `BEST` (popularity), `LATEST`, `REVIEW`, `LOW_PRICE`, or `HIGH_PRICE`. Default `BEST`. |
| `maxItems` | integer | Max products to collect. Default `100`. |
| `proxyConfiguration` | object | Apify Proxy settings. `RESIDENTIAL` recommended for large runs. |

#### Common category codes (category mode)

| Code | Category |
|------|----------|
| `268100100` | Women's Clothing |
| `272100100` | Men's Clothing |
| `270100100` | Women's Shoes |
| `271100100` | Women's Accessories |
| `275100100` | Men's Accessories |
| `292100100` | Kitchen / Living |

#### Input example

```json
{
  "mode": "search",
  "query": "nike",
  "sort": "BEST",
  "maxItems": 100
}
```

```json
{
  "mode": "category",
  "query": "268100100",
  "sort": "BEST",
  "maxItems": 200
}
```

***

### Output

Each product is one dataset record. Prices are in KRW (Korean won). `rating` is on a 0–5 scale. `rank` is populated when `sort` is `BEST`.

```json
{
  "source": "29cm",
  "product_id": "3819652",
  "name": "에브리데이 플러스 라이트웨이트 M - 블랙:화이트 / DX1158-010",
  "brand": "NIKE",
  "price_krw": 22000,
  "sale_price_krw": 19800,
  "discount_rate": 10,
  "currency": "KRW",
  "rating": 5.0,
  "review_count": 2,
  "heart_count": 30,
  "is_sold_out": false,
  "category": "남성액세서리/양말/중목/장목 양말",
  "rank": 4,
  "url": "https://www.29cm.co.kr/products/3819652",
  "image_url": "https://img.29cm.co.kr/item/202603/11f117807d5d38a8a540f9aea7f5035a.jpg",
  "scraped_at": "2026-07-09T10:00:44+09:00"
}
```

A full 40-item sample from a real run is in [`samples/sample-output.json`](samples/sample-output.json).

| Field | Meaning |
|-------|---------|
| `source` | Always `"29cm"`. |
| `product_id` | 29CM item number. |
| `name` | Product name. |
| `brand` | Brand display name (English where available, else Korean). |
| `price_krw` | Original/list (consumer) price, KRW. |
| `sale_price_krw` | Discounted price if on sale, else `null`. |
| `discount_rate` | Discount percentage (0 when not on sale). |
| `currency` | Always `"KRW"`. |
| `rating` | Average review score, 0–5. |
| `review_count` | Number of reviews. |
| `heart_count` | Number of users who wishlisted ("hearted") the product. |
| `is_sold_out` | Whether the product is sold out. |
| `category` | Category path (search mode) or the input category code (category mode). |
| `rank` | Popularity rank, when `sort` is `BEST`. |
| `url` | Product page URL. |
| `image_url` | Product image URL. |
| `scraped_at` | ISO-8601 timestamp (KST, UTC+9). |

***

### Use cases

- **K-fashion & lifestyle trend research** — track which designer brands and price points are climbing 29CM's popularity rankings week over week.
- **Dropshipping / product sourcing** — build a catalog of trending Korean designer products with images, brands, and prices to source or resell.
- **Price & discount monitoring** — watch `price_krw` vs `sale_price_krw` and `discount_rate` over time to catch drops and benchmark competitor pricing.
- **AI agents & datasets** — feed structured fashion/lifestyle data into recommendation models, market dashboards, or LLM agents.

***

### ❓ FAQ

**Is it legal to scrape this data?**
This actor collects only public, non-personal catalog data — the same product listings any 29CM visitor sees without logging in. No personal data is collected. You are responsible for how you use the data; see the legality note below.

**What does it cost in practice?**
$2.50 per 1,000 results (launch pricing), plus a few cents of platform usage. Example: a 500-result daily pull costs about $1.25/day. Apify's free $5 monthly credit covers ~2,000 results.

**Do I need to configure proxies?**
No — the default settings work out of the box. For large runs (high `maxItems`), enabling Apify Proxy with the `RESIDENTIAL` group is recommended to avoid 403/429 blocks; see the proxy note below.

**How fresh is the data?**
Every run scrapes the live site at run time. Schedule the actor for recurring snapshots.

**What is NOT included?**
Per-review text and ingredient/detail-page data are not collected — this actor returns list/aggregate product data only. Category-mode pagination is best-effort and may return fewer than `maxItems` on very deep crawls (search mode paginates cleanly).

***

### 🤖 Use with AI agents (MCP)

Call this Actor as a tool from Claude or any MCP-compatible AI agent — no glue code. Point your MCP client at Apify's server, scoped to this Actor:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=kdatafactory/29cm-scraper",
      "headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }
    }
  }
}
```

Your agent can then pull 29CM curated product listings on demand — no scraping code in your app. Grab a free token from [Apify → Integrations](https://console.apify.com/settings/integrations).

### 🇰🇷 More Korean data actors

This actor is part of a suite of Korean-platform scrapers by the same maintainer:

- [wconcept-scraper](https://apify.com/kdatafactory/wconcept-scraper) — W Concept contemporary designer fashion products and prices.
- [musinsa-scraper](https://apify.com/kdatafactory/musinsa-scraper) — Musinsa, Korea's largest fashion platform: products and rankings.
- [zigzag-scraper](https://apify.com/kdatafactory/zigzag-scraper) — Zigzag women's fashion products, prices, and trends.

Browse all: [apify.com/kdatafactory](https://apify.com/kdatafactory)

***

### Rate limiting & legality

- The actor collects **only public, non-authenticated data**. It never logs in and never touches private endpoints.
- **No personal data** is collected — no seller or reviewer names, profiles, or IDs. Only item/product data (name, brand, price, aggregate rating/review/heart counts, image).
- Requests are rate-limited: one page at a time with a ≥ 500 ms delay between requests, to stay gentle on 29CM's servers.
- You are responsible for using the data in line with 29CM's terms of service and applicable law.

#### ⚠️ Proxy recommendation

29CM may block datacenter IPs or high request volumes. For reliable runs — especially at higher `maxItems` — enable **Apify Proxy with the `RESIDENTIAL` group**. The actor automatically uses the proxy configuration you provide (via `proxyConfiguration` in input) and runs direct when none is set. If you see repeated `API HTTP 403/429` errors in the log, switch on residential proxy.

#### Known limitations

- **Category-mode pagination** is best-effort: 29CM's category feed can reshuffle between pages, so the actor de-duplicates by product id and may return fewer than `maxItems` for very deep category crawls. **Search mode paginates cleanly** and is the recommended path for large collections.
- Per-review text and ingredient/detail-page data are **not** collected (they load client-side and would require reviewer-identity handling); this actor returns list/aggregate product data only.

***

*If this actor saves you time, a rating on the [Store page](https://apify.com/kdatafactory/29cm-scraper) helps a solo maintainer a lot. Found an issue? Open it in the Issues tab — I respond fast.*

# Actor input Schema

## `mode` (type: `string`):

What to scrape. 'ranking' returns the REAL 29CM 베스트 Top-100 exactly as users see it at 29cm.co.kr/best-products (a stable, deterministic ranking segmented by gender/age/period/category — set those below). 'search' returns products matching a keyword (deep, reliable pagination). 'category' returns 29CM's category browse feed for a large-category code (note: this feed is rotated by 29CM and is NOT the fixed ranking — use 'ranking' for that).

## `rankingCategory` (type: `string`):

Which 베스트 category ranking to pull. Leave blank for the site-wide OVERALL ranking (all categories). Korean name or English alias: 뷰티(beauty), 여성의류(women), 남성의류(men), 여성가방, 남성가방, 여성주얼리, 남성주얼리, 가구/인테리어, 가전, 푸드(food), 키즈(kids). You may also pass a raw numeric largeId code.

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

29CM personalises its ranking by shopper segment. ALL = the un-segmented ranking; F / M = women's / men's ranking. NOTE: 29CM's own /best-products page defaults to gender=F, age=THIRTIES — set those to reproduce the exact default on-site view.

## `age` (type: `string`):

Age segment for the ranking. ALL = un-segmented. 29CM's on-site default is THIRTIES.

## `period` (type: `string`):

Time window the ranking is computed over. HOURLY = realtime (29CM's on-site default), DAILY / WEEKLY / MONTHLY = longer windows (more stable, better for trend feeds).

## `query` (type: `string`):

For 'search' mode: a keyword (e.g. 'nike', 'coat', '가디건'). For 'category' mode: a 29CM large-category code (e.g. '268100100' Women's Clothing, '272100100' Men's Clothing). Ignored in 'ranking' mode.

## `sort` (type: `string`):

Ordering of the search/category feed. BEST = popularity, LATEST = newest, REVIEW = most reviewed, LOW\_PRICE / HIGH\_PRICE = by price. Ignored in 'ranking' mode.

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

Maximum number of products to collect. The 베스트 ranking is typically a Top-100.

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

Apify Proxy settings. RESIDENTIAL is recommended for large runs. Leave default to run without a proxy (fine for small local tests).

## Actor input object example

```json
{
  "mode": "ranking",
  "rankingCategory": "",
  "gender": "ALL",
  "age": "ALL",
  "period": "DAILY",
  "query": "nike",
  "sort": "BEST",
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("kdatafactory/29cm-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 = {}

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

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

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

```

## CLI example

```bash
echo '{}' |
apify call kdatafactory/29cm-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=kdatafactory/29cm-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/ilOuTRZ1fgk0dIIf2/builds/RCZN2syPFrNmjMsLN/openapi.json
