# Naver Place Scraper - Korea Business & Reviews API (`kdatafactory/naver-place-scraper`) Actor

Extract Korean local business listings from Naver Place as clean English JSON: name, category, road and lot address, phone, WGS84 coordinates, visitor rating, review counts and the blog/cafe review count Korean marketers track. Around 60 businesses per keyword.

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

## Pricing

from $2.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?

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

## Naver Place Scraper — Korean Business Listings & Reviews

Scrape **business listings and reviews from [Naver Place](https://map.naver.com) / Naver Maps** — Korea's dominant local-search and maps platform — by keyword. Give it a Korean search query like `강남역 카페` ("Gangnam Station cafe") and get back clean, structured JSON for every business: name, category, address, phone, rating, review count, plus the review text, rating, date and keywords.

Naver is where Korean consumers actually find and review local businesses (Google Maps has minimal coverage in Korea). If you need Korean local-business data, this is the source.

> **Privacy-first.** This actor **never collects reviewer names, IDs, or profile links.** Reviews contain only `text`, `rating`, `date`, and `keywords`. Business phone numbers and addresses are public business-registration information and are included.

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

***

### What it does

- Takes a Naver Maps search query (location + category works best).
- Pages through Naver's public, server-rendered search results.
- Extracts each business and its attached visitor reviews.
- Emits one record per business, with a nested `reviews` array, matching a stable schema.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `searchQuery` | string | — (required) | Naver Maps query, e.g. `강남역 카페`, `홍대 맛집`, `제주 흑돼지`. |
| `maxPlaces` | integer | `20` | Max businesses to scrape. |
| `includeReviews` | boolean | `true` | Attach visitor reviews to each business. |
| `maxReviewsPerPlace` | integer | `20` | Max reviews per business. |
| `proxyConfiguration` | object | RESIDENTIAL / KR | Proxy settings (see *Proxy & rate limits*). |

#### Input example

```json
{
  "searchQuery": "강남역 카페",
  "maxPlaces": 20,
  "includeReviews": true,
  "maxReviewsPerPlace": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "KR"
  }
}
```

### Output

One dataset item per business. Reviews are nested under `reviews`. This is **real output** from a live run for `강남역 카페` (see `samples/sample-output.json` for 27 full records):

```json
{
  "source": "naver_place",
  "place_id": "1668757640",
  "name": "퍼스트커피랩 강남점",
  "category": "카페,디저트",
  "address": "서울 강남구 역삼동",
  "road_address": "봉은사로6길 39 1층",
  "phone": "0507-1315-7680",
  "rating": null,
  "review_count": 2792,
  "url": "https://m.place.naver.com/place/1668757640/home",
  "scraped_at": "2026-07-07T12:00:00+09:00",
  "reviews": [
    {
      "place_id": "1668757640",
      "rating": null,
      "text": "디저트들이 다양하고 커피가 맛있어요 :) 베이커리부터 구움과자 마들렌하고 휘낭시에까지 라인업 완벽!",
      "date": null,
      "keywords": ["디저트", "커피", "베이커리", "구움과자", "마들렌", "휘낭시에"]
    }
  ]
}
```

#### Field notes

- `place_id` — Naver's stable business identifier; use it to build the URL or re-fetch.
- `phone` — the business's public number (Naver's public safe-number is used when a raw landline is not exposed). Public business info.
- `rating` — Naver has deprecated the visible 1–5 star average for many businesses, so this is frequently `null`. `review_count` is the reliable popularity signal.
- `keywords` — salient tokens Naver highlights in each review snippet; a ready-made signal for sentiment/topic analysis.
- `date` — populated when the review source exposes a visit date; `null` for search-embedded snippets.

### Use cases

- **Local SEO monitoring** — track how your (or a client's) business ranks for target queries on Naver, and monitor review volume/velocity over time.
- **Review sentiment analysis for Korean market entry** — pull thousands of real Korean-language reviews and keywords for a category or district before launching, and feed them straight into an LLM or NLP pipeline. No PII to scrub — reviewer identity is never collected.
- **Competitor research** — snapshot every competitor in a district (address, phone, category, review counts) in one run.
- **AI agents & lead lists** — structured Korean local-business data for RAG, enrichment, or outreach.

### Proxy & rate limits

Naver aggressively **rate-limits and CAPTCHA-gates datacenter IPs.** This actor uses two paths:

1. **Search-page path (primary).** Reads Naver's public server-rendered search results. This works from many IPs and returns the businesses plus a few embedded reviews each — this is what produced the samples in this repo, with **no proxy**.
2. **Per-place GraphQL path (deep reviews).** `pcmap-api.place.naver.com/graphql`, used when you request more reviews than the search page embeds. This endpoint **returns a CAPTCHA challenge for datacenter IPs** (`HTTP 405` + `title="captcha"`; evidence in `samples/graphql-block-evidence.html`). The actor detects this and **gracefully falls back** to the search-embedded reviews.

**For reliable, high-volume runs and deep per-place review pagination, use Apify Proxy with the `RESIDENTIAL` group and country `KR`** (the default in the input schema). The actor honours `proxyConfiguration` throughout. Without a residential IP you will still get businesses and a handful of reviews each, but review depth and total place coverage are limited by Naver's anti-bot.

The actor runs politely: effectively concurrency 1 with ≥600 ms between requests.

### Legality & data ethics

- Only **public** data is collected — no login, no private endpoints.
- **No personal data.** Reviewer names, IDs, and profiles are never read or stored. Reviews carry only text, rating, date, and keywords. Business phone/address are public business-registration details.
- You are responsible for using the output in compliance with Naver's terms and applicable law (e.g. PIPA, GDPR). Because no personal data is emitted, output is safe to feed directly into analytics and LLM pipelines.

### ❓ FAQ

**Is it legal to scrape this data?**
This actor collects only public business-listing data — the same listings and reviews any visitor sees on Naver Maps without logging in. Reviewer names, IDs, and profiles are never collected. You are responsible for how you use the data; see the legality note above.

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

**Do I need to configure proxies?**
No — the default settings work out of the box. For deep per-place review pagination and high-volume runs, Apify Proxy with the `RESIDENTIAL` group and country `KR` (the input default) is recommended, since Naver CAPTCHA-gates datacenter IPs on its per-place API.

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

**What is NOT included?**
Reviewer identity (names, IDs, profile links) is never collected — by design. The star `rating` is frequently `null` because Naver has deprecated the visible average for many businesses (use `review_count` instead), and review `date` is `null` for search-embedded snippets.

### 🤖 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/naver-place-scraper",
      "headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }
    }
  }
}
```

Your agent can then pull Korean business listings from Naver Place 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:

- [popply-scraper](https://apify.com/kdatafactory/popply-scraper) — Korean pop-up store events and locations
- [bunjang-scraper](https://apify.com/kdatafactory/bunjang-scraper) — Bunjang secondhand-marketplace listings and prices
- [kurly-scraper](https://apify.com/kdatafactory/kurly-scraper) — Market Kurly grocery products, prices, and reviews

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

### Local development

```bash
npm install
## put input in ./storage/key_value_stores/default/INPUT.json, then:
npm start   # results land in ./storage/datasets/default
```

***

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

### Coverage (measured, 2026-08-20)

This actor reads Naver's **place-list** endpoint, which returns roughly **60 businesses per keyword** and honours a larger `display` request (verified: 107 for a broad query). Earlier builds read Naver's integrated-search page instead, which embeds only ~7 places per query and ignores its paging offset — so a run was capped at 7 regardless of `maxPlaces`. That is fixed.

Each row carries WGS84 `latitude` / `longitude`, and `blog_cafe_review_count` alongside the visitor review total, since the blog/cafe figure is the one Korean marketers track separately.

# Actor input Schema

## `searchQuery` (type: `string`):

A Naver Place / Naver Maps search query, exactly as you would type it into Korean Naver Maps. Combine a location and a category for best results, e.g. "강남역 카페" (Gangnam Station cafe), "홍대 맛집" (Hongdae restaurants), "제주 흑돼지" (Jeju black pork).

## `maxPlaces` (type: `integer`):

How many businesses to return for the query. Naver's place list serves roughly 60 results per keyword and up to ~300 when asked for more, so a broad query can fill a large maxPlaces while a narrow one returns everything it has and stops.

## `includeReviews` (type: `boolean`):

If enabled, each place record is enriched with visitor reviews (text, rating, date, keywords). Reviewer identity is never collected.

## `maxReviewsPerPlace` (type: `integer`):

Maximum number of reviews to collect per place (only used when Include reviews is on).

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

Naver aggressively rate-limits and CAPTCHA-gates datacenter IPs. RESIDENTIAL proxies (Apify Proxy, group RESIDENTIAL, country KR) are strongly recommended for reliable runs and for deep per-place review pagination.

## Actor input object example

```json
{
  "searchQuery": "강남역 카페",
  "maxPlaces": 20,
  "includeReviews": true,
  "maxReviewsPerPlace": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "KR"
  }
}
```

# Actor output Schema

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

Every record 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 = {
    "searchQuery": "강남역 카페"
};

// Run the Actor and wait for it to finish
const run = await client.actor("kdatafactory/naver-place-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 = { "searchQuery": "강남역 카페" }

# Run the Actor and wait for it to finish
run = client.actor("kdatafactory/naver-place-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 '{
  "searchQuery": "강남역 카페"
}' |
apify call kdatafactory/naver-place-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kdatafactory/naver-place-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/8BeMVtmh0VTtoIn6H/builds/F7zJpXv1D5MxtQhR7/openapi.json
