# Hwahae Scraper - K-Beauty Rankings API (Korean Skincare) (`koreadata-lab/hwahae-kbeauty-ranking-tracker`) Actor

Scrape Hwahae (화해) K-beauty rankings: daily top-20 Korean skincare and makeup bestsellers by category, trending, skin type and age. Rank change, rating, review count, price, English names. JSON/CSV, no login.

- **URL**: https://apify.com/koreadata-lab/hwahae-kbeauty-ranking-tracker.md
- **Developed by:** [Koreadata Lab](https://apify.com/koreadata-lab) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 ranking rows

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?

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

## Hwahae Scraper - K-Beauty Rankings API (Korean Skincare)

A **Hwahae scraper** for daily **top-20 Korean cosmetics rankings** from **Hwahae (화해)** public ranking pages, Korea's #1 cosmetics review app (10M+ reviews): **by category, trending (급상승), by skin type, and by age group**. Each product comes with rank change, rating, review count, price, English category names and an **aggregated review-topic summary** (e.g. "Soothing", "Non-sticky", "Strengthens skin barrier"). It is built for K-beauty resellers, Amazon/TikTok Shop sellers, brand managers and trend reports.

> **Live-tested on Apify: YES (2026-10-29).** 60 ranking rows from the public ranking pages (top 20 per ranking).

### Why this actor

- **All four Hwahae ranking types** (category / trending / skin type / age), top 20 of each, from the public ranking pages only.
- **Hwahae's own rank delta** (`hwahaeRankDelta`, `isNewOnHwahae`) **plus** a change vs your previous run.
- **English everywhere it matters:** 140+ category names, skin types, age groups and the most common review topics come from a static dictionary, and Korean brand names are romanized.
- **No reviewer data:** only product-level aggregates. No review texts, nicknames, ages or skin profiles of individual users.

### Input

```json
{ "rankingType": "skin", "skinTypes": ["민감성", "지성"], "categoryCodes": ["001:001", "001:004"], "maxRank": 20 }
```

Common category codes: `001` all, `001:001` skincare, `001:001:001` toner, `001:001:003` essence/serum, `001:001:005` cream, `001:002` cleansing, `001:003` masks, `001:004` sun care, `001:004:001` sunscreen, `001:005` base makeup, `001:005:005` cushion, `001:007` lip, `001:009` hair, `003` men.

### Output

One item per ranked product. Real row from the 2026-10-29 skincare ranking (shortened):

```json
{
  "rankingType": "category", "categoryCode": "001:001", "categoryKo": "스킨케어", "categoryEn": "Skincare",
  "rank": 2, "hwahaeRankDelta": 1, "isNewOnHwahae": false,
  "productId": 2197950, "productName": "히알루로닉 붐 세럼 워터 드롭", "brandName": "아비브", "brandNameRomanized": "Abib",
  "packageInfo": "1.69 fl. oz. 50 mL", "listPriceKrw": 32000, "reviewCount": 3390, "rating": 4.64,
  "topReviewTopics": [{"topicEn": "Breathable"}, {"topicEn": "Blends in"}, {"topicEn": "Has granules"}],
  "rankingUpdatedAt": "2026-10-29 05:00:00", "url": "https://www.hwahae.co.kr/goods/77974"
}
```

Full field list: see the Output tab (dataset schema).

### Pages used (public only)

- `https://www.hwahae.co.kr/rankings?english_name=…&theme_id=…`: the public ranking page (allowed by robots.txt). Ranks 1 to 20 come from the page's `__NEXT_DATA__`.
- `https://www.hwahae.co.kr/robots.txt` is read first; any disallowed path stops the run.
- The actor does **not** call Hwahae's internal app API (the "load more" JSON behind the page), so ranks 21 to 100 are not available. `maxRank` is capped at 20.
- Rate: 1 request every 2.5 s, sequential.

### Limitations

- Hwahae updates category rankings about weekly and trending rankings daily. Check `rankingUpdatedAt`.
- `shopOfferPriceKrw` is the price of Hwahae's shop offer, which can be a bundle. Use `listPriceKrw` with `packageInfo` for the single-product list price.
- Review-topic English labels cover the most common topics. Others are `null`, with the Korean kept.
- Only the top 20 per ranking. Ranks 21 to 100 would need Hwahae's internal API, which this actor does not use.
- This is an unofficial integration and may break if Hwahae changes its site.

### API keys

None. This actor reads public pages only, takes no credentials and stores none.

### Pricing (pay per event)

- `ranking-row`: **$4.00 per 1,000 rows** (English names, categories and review topics included), plus Apify's tiny `apify-actor-start` event.
- **Platform usage is included**: you pay only the event prices, not the compute.
- One ranking (20 rows) costs about **$0.08**; 15 rankings (300 rows) about **$1.20**.
- Set **Max total charge** for a run to cap spend; the actor stops early when it is reached.

### FAQ

**Do I need a Hwahae account or API key?** No. It reads Hwahae's public ranking pages only.

**How fresh is the data?** Trending rankings change daily and category rankings about weekly. Each row carries `rankingUpdatedAt`. Schedule the actor daily and use `rankChangeVsLastRun` to see movement.

**Can I get ranks beyond 20?** No. Ranks 21+ sit behind Hwahae's internal API, which this actor does not use.

**Can I use it for Olive Young or Glowpick?** Not this actor. Olive Young blocks crawlers in robots.txt, so Hwahae is the legal Korean K-beauty ranking source this actor covers.

**Is there an English demo of the data?** Yes: [K-Beauty Now](https://whistlewhistle311-web.github.io/kbeauty-now/) publishes the same rankings in English every day.

# Actor input Schema

## `rankingType` (type: `string`):

Which Hwahae ranking to read.

## `categoryCodes` (type: `array`):

Hwahae category codes. 001 = all; 001:001 Skincare; 001:001:001 Toner; 001:001:003 Essence/serum; 001:001:005 Cream; 001:002 Cleansing; 001:003 Masks; 001:004 Sun care; 001:004:001 Sunscreen; 001:005 Base makeup; 001:005:005 Cushion; 001:006 Eye makeup; 001:007 Lip makeup; 001:008 Body; 001:009 Hair; 001:011 Perfume; 001:013 Inner beauty; 003 Men. Max 30.

## `skinTypes` (type: `array`):

Used when ranking type = skin.

## `ageGroups` (type: `array`):

Used when ranking type = age.

## `maxRank` (type: `integer`):

How deep to read each ranking. Only the public ranking page is read, which shows the top 20.

## `trackHistory` (type: `boolean`):

Hwahae already provides its own rank change (hwahaeRankDelta). This adds a change vs YOUR last run (useful when you run less often than Hwahae updates).

## `historyStoreName` (type: `string`):

Named key-value store for run-to-run history.

## Actor input object example

```json
{
  "rankingType": "category",
  "categoryCodes": [
    "001",
    "001:001",
    "001:004"
  ],
  "skinTypes": [
    "민감성"
  ],
  "ageGroups": [
    "20대"
  ],
  "maxRank": 20,
  "trackHistory": true,
  "historyStoreName": "hwahae-ranking-history"
}
```

# Actor output Schema

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

All result rows in the default dataset.

# 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("koreadata-lab/hwahae-kbeauty-ranking-tracker").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("koreadata-lab/hwahae-kbeauty-ranking-tracker").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 '{}' |
apify call koreadata-lab/hwahae-kbeauty-ranking-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,koreadata-lab/hwahae-kbeauty-ranking-tracker"
        }
    }
}
```

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/8UUeDflm8Baj330cq/builds/YrwlZORzUeQoIJ4lv/openapi.json
