# Naver Map Scraper (Naver Place Search) (`magenta_courser/naver-place-search-scraper`) Actor

Search Naver Map (Naver Place) by keyword and get Korean business listings: restaurants, cafes, clinics, salons and shops in Seoul and all of South Korea. Returns name, category, address, phone, coordinates, rating and review counts as flat JSON.

- **URL**: https://apify.com/magenta\_courser/naver-place-search-scraper.md
- **Developed by:** [SUNGHWAN CHO](https://apify.com/magenta_courser) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 places

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 Search Scraper

Search **Naver Map (Naver Place)** by keyword and get structured Korean business listings — restaurants, cafes, clinics, salons, shops and any other local business in South Korea.

Naver Map is the dominant map and local search service in Korea, with far better coverage of Korean businesses than Google Maps. This Actor gives you its search results as clean JSON with English field names.

### What you get

For each search query, up to about 300 places in Naver's own ranking order:

- Name, category and business type
- Road address, lot-number address and district
- Phone number
- Latitude and longitude
- Visitor rating, visitor review count, blog review count
- Booking and Naver Pay availability, TalkTalk chat link
- Amenities (parking, takeout, Wi-Fi, group seating, …)
- Image URLs
- Direct Naver Map URL

No login, no API key and no browser needed, so runs are fast.

### Use cases

- **Lead generation** — build lists of Korean businesses by area and category, with phone numbers and addresses
- **Market research** — count and compare competitors in a neighborhood before entering the Korean market
- **Local SEO** — check where a business ranks on Naver Map for a keyword
- **Location data for AI agents and apps** — feed Korean place data into your own pipeline

### Input

| Field | Description |
|---|---|
| `queries` | Search keywords, one per line. Korean keywords work best: `강남 맛집` (Gangnam restaurants), `성수 카페` (Seongsu cafes), `홍대 미용실` (Hongdae hair salons). Combine an area with a category. |
| `maxPlacesPerQuery` | Maximum places per query (1–300). Default 50. |
| `proxyConfiguration` | Proxy settings. Keep the Apify Proxy enabled; Naver rate-limits repeated requests from one IP. |

```json
{
  "queries": ["강남 맛집", "성수 카페"],
  "maxPlacesPerQuery": 100
}
```

### Output

One dataset item per place:

```json
{
  "source": "naver",
  "query": "성수 카페",
  "rank": 1,
  "id": "1922651675",
  "name": "노틀던",
  "category": "카페,디저트",
  "businessType": "cafe",
  "roadAddress": "서울숲2길 11 1층",
  "address": "서울특별시 성동구 성수동1가 685-501 1층",
  "district": "서울 성동구 성수동1가",
  "phone": null,
  "latitude": 37.5473614,
  "longitude": 127.0400154,
  "visitorReviewScore": 4.97,
  "visitorReviewCount": 1157,
  "blogCafeReviewCount": 1461,
  "bookingReviewCount": 0,
  "hasBooking": true,
  "hasNaverPay": true,
  "talktalkUrl": "http://talk.naver.com/wya8yhi?frm=pnmb",
  "amenities": ["포장", "예약", "단체 이용 가능", "간편결제", "제로페이"],
  "promotion": null,
  "isNewOpening": false,
  "imageUrl": "https://naverbooking-phinf.pstatic.net/20260824_127/1787572619818421QO_JPEG/image.jpg",
  "imageUrls": ["https://naverbooking-phinf.pstatic.net/20260824_127/1787572619818421QO_JPEG/image.jpg"],
  "imageCount": 9,
  "url": "https://map.naver.com/p/entry/place/1922651675",
  "scrapedAt": "2026-10-01T06:24:41.088Z",
  "schemaVersion": 2
}
```

Every row has every field, always in this order. A value Naver did not provide is `null`, never a missing key. For the review counts, `0` means Naver reports zero reviews and `null` means Naver did not provide the count. `schemaVersion` changes when fields are added or their meaning changes (version 2, 2026-10-01: added `source` and `schemaVersion`; missing counts are now `null` instead of `0`).

Export the dataset as JSON, CSV or Excel, or read it through the Apify API.

### Run summary: did every query finish?

Each run saves a free summary in the key-value store as `RUN_SUMMARY` (the **Run summary** link on the Output tab, or `GET https://api.apify.com/v2/key-value-stores/{defaultKeyValueStoreId}/records/RUN_SUMMARY`). It is not a dataset row, so it is not billed. One entry per query:

```json
{
  "query": "성수 카페",
  "status": "completed",
  "stopReason": "maxPlacesReached",
  "reportedTotal": 1843,
  "returnedCount": 100,
  "coverageLimit": 100,
  "errorMessage": null
}
```

- `status`: `completed`, `partial` (some places saved, then Naver kept rejecting requests), `failed` (nothing saved for this query), `budgetLimited` (your "Maximum cost per run" was reached).
- `stopReason`: `maxPlacesReached`, `endOfResults`, `noResults`, `coverageLimitReached` (Naver's limit of about 300 places per query), `requestFailed`, `chargeLimitReached`, `notStartedChargeLimit`.
- `reportedTotal` is the total Naver reports for the query; `returnedCount` is the number of places actually saved.

The run fails only when every query failed. If some queries fail, the other results are kept and the run succeeds; check `RUN_SUMMARY` to re-run just the failed ones.

### Tips

- **Go beyond 300 places** by splitting an area into smaller ones: instead of `서울 카페`, search `성수 카페`, `연남 카페`, `한남 카페`, and so on. Use the `id` field to remove duplicates.
- **Sponsored listings are excluded**; `rank` reflects the organic order.
- Text fields such as names, categories and amenities are returned in Korean, as shown on Naver.
- Some businesses do not publish a phone number or a rating; those fields are `null`.

### Next step: get reviews

Pass the `id` of each place to [Naver Place Reviews Scraper](https://apify.com/magenta_courser/naver-place-reviews-scraper) to get its visitor reviews: rating, text, visit date, keywords and owner replies.

Example: search, then send the IDs of the places you want to the reviews Actor.

1. Run this Actor with `{"queries": ["성수 카페"], "maxPlacesPerQuery": 20}`.
2. Take the `id` values from the dataset, e.g. `https://api.apify.com/v2/datasets/{datasetId}/items?fields=id,name&format=json`.
3. Run Naver Place Reviews Scraper with those IDs:

```json
{
  "places": ["1922651675", "1234567890"],
  "maxReviewsPerPlace": 100
}
```

The reviews Actor is billed per review, so pick the places you need instead of sending every search result.

### Also search Kakao Map

[Kakao Map Place Search Scraper](https://apify.com/magenta_courser/kakaomap-place-search-scraper) takes the same input and returns the same field names in the same order, up to 500 places per query. Run both with the same keywords and append the datasets into one table; `source` (`naver` or `kakao`) tells the rows apart.

When merging:

- **Use `source` + `id` as the row key.** Naver and Kakao IDs are separate systems, so the same number can mean different places.
- **Decide that two rows are the same business by phone number, address and coordinates**, not by name. Many different businesses share a name (chains, common names like `스타벅스` or `김밥천국`). If phone, address and coordinates do not agree, keep the rows separate.
- Ratings and review counts come from each service and are not comparable one-to-one.

### Notes

This Actor collects only publicly visible business listing data. It does not collect personal data of reviewers or log in to any account.

# Actor input Schema

## `queries` (type: `array`):

Keywords to search on Naver Map, one per line. Korean works best, e.g. 강남 맛집 (Gangnam restaurants), 성수 카페 (Seongsu cafes), 홍대 미용실 (Hongdae hair salons).

## `maxPlacesPerQuery` (type: `integer`):

Maximum number of places to return for each query. Naver returns up to about 300 places per query.

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

Naver rate-limits repeated requests from one IP, so a proxy is recommended.

## Actor input object example

```json
{
  "queries": [
    "강남 맛집"
  ],
  "maxPlacesPerQuery": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `places` (type: `string`):

All scraped places as dataset items.

## `runSummary` (type: `string`):

Per-query status (completed, partial, failed, budgetLimited), stop reason, reported total and returned count. Not billed.

# 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 = {
    "queries": [
        "강남 맛집"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("magenta_courser/naver-place-search-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 = {
    "queries": ["강남 맛집"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("magenta_courser/naver-place-search-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 '{
  "queries": [
    "강남 맛집"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call magenta_courser/naver-place-search-scraper --silent --output-dataset

```

## MCP server setup

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