# Naver Place & Map Scraper (Korea) — hours, menus, coordinates (`vibement/naver-place-scraper`) Actor

- **URL**: https://apify.com/vibement/naver-place-scraper.md
- **Developed by:** [Vibement Labs](https://apify.com/vibement) (community)
- **Categories:** Lead generation, Travel, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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 & Map Scraper — privacy-safe, analysis-ready Korean business data

- **Reviews without reviewer identity**: text, stars and dates only. No nicknames, profile links, user IDs or reviewer photos, and phone numbers or emails inside review text are masked (`***`). Reviews are off by default.
- **Addresses you can join**: road and lot (jibun) address plus `sido` / `sigungu` / `dong` columns, ready to merge with Korean public datasets.
- **Phones you can dial**: E.164 (`+82…`) plus a `phoneType` flag (landline, mobile, Naver 0507 forwarding, 15xx representative) and a `phoneStatus` that tells you *why* a phone is missing (owner hid it vs. never registered).
- **No silent failures**: every keyword gets a status row (Naver's total vs. returned, duplicates removed, failed IDs) in the `RUN_SUMMARY` record. A keyword that returns nothing fails the run instead of ending "Succeeded" with no data, and rows whose detail page could not be loaded are never charged.
- Full details per place: per-day hours (break time, last order), menus with prices, rating, review counts, coordinates. No browser, so runs are fast and cheap.

네이버 플레이스·지도 업체 정보를 분석에 바로 쓰는 형태로 드립니다.
리뷰는 본문·별점·날짜만 드립니다(기본값 꺼짐). 작성자 닉네임·프로필·사진은 수집하지 않고, 본문 속 전화번호·이메일은 `***`로 가립니다.
주소는 도로명·지번에 시도/시군구/읍면동 열을 더해 공공데이터와 바로 붙습니다.
전화는 +82 국제형식과 유형(일반·휴대폰·0507 안심번호·15xx 대표번호), 빈 이유(사장님 비공개/미등록)까지 드립니다.
검색어마다 「네이버 총건수 대비 수집 건수」를 남기고, 상세를 못 가져온 행에는 과금하지 않습니다.

### What you get (one row per place, in Naver's rank order)

- `placeId`, `name`, `category`, `rank` (position in Naver's result list), `query`
- `roadAddress`, `jibunAddress`, `sido`, `sidoFull`, `sigungu`, `dong`, `latitude`, `longitude`
  (`postalCode` is filled only if Naver's page carries one — currently it usually does not, so expect `null`)
- `phone`, `phoneE164`, `phoneType` (`virtual0507` | `landline` | `mobile` | `representative` | `null`),
  `phoneStatus` (`public` | `hiddenByOwner` | `notRegistered` | `unknown` when details are off), plus `virtualPhone` and Naver's raw `phoneHidden` flag
- `businessHours` — with details on: per-day `open`/`close`, `breakTimes`, `lastOrder`, current `status`, plus a `raw` text line. For lodging (pensions etc.) Naver has no opening hours, so `type: "accommodation"` with `checkIn`/`checkOut` is returned instead. Without details only a status summary is returned.
- `visitorReviewCount`, `blogReviewCount`, `rating`
- `menus` `[{ name, price }]` (restaurants/cafés, when the owner lists them), `conveniences`, `bookingUrl`
- `placeUrl` (Naver Map link), `mobileUrl`, `scrapedAt`
- `detailError` — set only when the place page could not be loaded after 8 tries; the row keeps the list values (name, address, coordinates, phone, review count) and is not charged
- Optional `reviews` `[{ text, rating, date (YYYY-MM-DD), dateRaw }]`

### Input

| Field | Default | Notes |
|---|---|---|
| `queries` | — | Required. Include the area in the keyword. Max 20 per run. |
| `maxResultsPerQuery` | 50 | Max 100 per query (Naver's mobile list limit). Split by neighborhood for more. |
| `includeDetails` | true | One extra request per place (hours per day, menus, phone status). |
| `includeReviews` | false | Review text, rating and date only; phones/emails in text masked. |
| `maxReviewsPerPlace` | 10 | Max 50. |
| `searchLatitude` / `searchLongitude` | Seoul City Hall | Map center Naver requires; affects ranking/distance only. |
| `proxyConfiguration` | Apify Proxy | Spreads requests over several IPs. |

### Run summary

The key-value store record `RUN_SUMMARY` lists, per query: `requested`, `naverTotal`, `returned`, `duplicatesRemoved`, `failedDetailIds`, `status`. The same lines are written to the log.

### Fair use

- Business listings only: name, category, address, the business phone the owner published, coordinates, hours, menus, review counts.
- No reviewer identity is ever collected. Review text is optional, off by default, capped at 50 per place, and phone numbers/emails inside it are masked.
- Not for mirroring Naver's database or building a competing directory or map service. Use it for research, analysis, and finding businesses.
- Per-run caps are fixed in code: 20 queries per run, 100 places per query, 50 reviews per place. Requests are paced at low concurrency; if Naver refuses requests, the run waits and then stops with partial results (it never switches IPs or solves captchas). Failed rows are not charged.
- To request removal of your business data or to ask us to stop, open an issue in this actor's **Issues** tab. We respond and act on it.

### 공정 이용

- 업체 정보만 드립니다: 상호, 업종, 주소, 사장님이 공개한 업체 전화, 좌표, 영업시간, 메뉴, 리뷰 수.
- 리뷰 작성자 정보는 수집하지 않습니다. 리뷰 본문은 선택(기본 꺼짐)이고, 곳당 최대 50건, 본문 속 전화번호·이메일은 가립니다.
- 네이버 데이터베이스를 복제하거나 경쟁 디렉터리·지도 서비스를 만드는 용도로 쓰지 마세요. 조사·분석·업체 탐색용입니다.
- 실행당 상한이 코드에 고정돼 있습니다: 검색어 20개, 검색어당 100곳(네이버 모바일 목록 한도), 곳당 리뷰 50건. 요청은 낮은 동시성으로 보내고, 네이버가 거절하면 기다렸다가 부분 결과로 멈춥니다(IP 교체·캡차 풀이 없음). 실패 행은 과금하지 않습니다.
- 업체 정보 삭제나 수집 중단을 원하시면 이 액터의 **Issues** 탭에 남겨 주세요. 확인 후 조치합니다.

### Notes

- Data is what Naver publicly shows. If a business did not register hours or a phone number, the field is `null` (see `phoneStatus` for phones).
- Review dates without a year (e.g. `10.14.수`) get the current year, or last year if that date would be in the future.
- No login, no captcha solving.

***

### 한국어 안내

네이버 지도·플레이스 검색 결과(예: `강남역 맛집`)를 장소별 한 줄로, 네이버 순위 순서대로 가져옵니다. 브라우저를 쓰지 않아 빠르고 저렴합니다.

- 가져오는 항목: 상호, 업종, 도로명·지번 주소, 시도·시군구·읍면동, 전화(+82 형식·유형·공개 상태), 위도·경도, 요일별 영업시간(브레이크타임·라스트오더 포함), 방문자·블로그 리뷰 수, 별점, 메뉴·가격, 네이버 지도 링크, 검색 순위
- 펜션·숙소는 네이버에 영업시간이 없어 체크인·체크아웃 시간을 대신 넣습니다.
- 상세 페이지를 8번 시도해도 못 가져온 곳은 `detailError` 를 표시하고 목록 값(이름·주소·좌표·전화·리뷰 수)을 남기며, 과금하지 않습니다.
- 리뷰 옵션을 켜면 리뷰 **본문·별점·날짜(YYYY-MM-DD)만** 가져옵니다. 작성자 닉네임·아이디·프로필·사진은 수집하지 않습니다(개인정보보호법).
- 검색어별 결과 요약은 `RUN_SUMMARY` 에 남습니다. 결과가 0건인 검색어가 있으면 실행을 실패로 표시합니다.
- 업체가 네이버에 등록하지 않은 정보는 빈 값(null)입니다.

# Actor input Schema

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

Keywords exactly as you would type them into Naver Map, e.g. '강남역 맛집', '부산 서면 카페', '제주 애월 펜션'. Put the area name in the query for best results. Fair-use cap: up to 20 queries per run (extra ones are skipped with a warning).

## `maxResultsPerQuery` (type: `integer`):

How many places to return per query, in Naver's ranking order. Max 100 per query (Naver's mobile list limit). For more coverage, split by neighborhood, e.g. "강남역 맛집", "역삼역 맛집".

## `includeDetails` (type: `boolean`):

Open each place page to get per-day business hours (open/close/break/last order), full addresses, menus with prices and rating. One extra request per place.

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

Off by default. Adds recent visitor review texts. Only review text, star rating and date are returned — never the reviewer's nickname, ID, profile or photos. Phone numbers and emails inside review text are masked as \*\*\*.

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

Used only when 'Include visitor reviews' is on. Hard cap 50.

## `searchLatitude` (type: `string`):

Naver needs a map center for search. Default is Seoul City Hall. It only affects ranking/distance, not which region is searched (the area name in the query decides that).

## `searchLongitude` (type: `string`):

See latitude.

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

Apify Proxy is recommended so requests are spread over several IPs.

## Actor input object example

```json
{
  "queries": [
    "강남역 맛집"
  ],
  "maxResultsPerQuery": 50,
  "includeDetails": true,
  "includeReviews": false,
  "maxReviewsPerPlace": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One record per place.

## `dataset` (type: `string`):

All places as a dataset.

## `summary` (type: `string`):

Per-query status: requested vs. returned, Naver's total, duplicates removed, failed detail IDs.

# 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("vibement/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 = {
    "queries": ["강남역 맛집"],
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vibement/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/4JmTwim2NhqE6lxOc/builds/JccwdnQJKwbVvDSKd/openapi.json
