# Naver Local Businesses Scraper (`automation-lab/naver-map-business-scraper`) Actor

Export public Naver local businesses from Korean Map search URLs: place IDs, categories, contacts, addresses, coordinates, review counts and booking flags. Bounded first-page snapshots with deduplication.

- **URL**: https://apify.com/automation-lab/naver-map-business-scraper.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.84 / 1,000 item processeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Local Businesses Scraper

Refresh datasets of **Naver local businesses** from exact Korean Naver Map search URLs. Get structured business identities, categories, public contact fields, addresses, coordinates, review counts and booking flags without collecting review text.

This is a first-page snapshot tool for Korean local-market research, agency directory refreshes and local SEO analysis. It does not promise exhaustive geographic coverage.

### What does it do?

Supply the exact Map search URL you want to snapshot. The Actor opens an anonymous Korean browser session with a lightweight search client, executes Naver's public session script, captures the public business search response and writes one row per unique place ID. It does not render the full interactive map. It processes URLs sequentially and stops at your global record limit.

### Who is it for?

Korean local SEO analysts, agencies refreshing business directories and researchers comparing local business listings can use these snapshots. It is not an exhaustive lead database.

### Why use it?

- Keep stable place IDs for joining successive snapshots.
- Preserve Korean names and source category labels without translation loss.
- Get contacts when already exposed in search, without expensive detail enrichment.
- Keep provenance: each row includes the originating URL, decoded query and extraction timestamp.
- Avoid mixing business records with reviews, photos or menu items.

### Getting started

1. Open Naver Map and search using a Korean location and business keyword, such as `서울 카페`.
2. Copy its `https://map.naver.com/p/search/...` URL.
3. Add it to `searchUrls` and choose `maxItems`.
4. Run the Actor and open the Businesses dataset.
5. Download JSON, CSV or Excel using Apify's dataset export tools.

```json
{
  "searchUrls": ["https://map.naver.com/p/search/%EC%84%9C%EC%9A%B8%20%EC%B9%B4%ED%8E%98?c=126.97825,37.566551,13,0,0,0,dh"],
  "maxItems": 20
}
```

### Inputs

| Field | Meaning |
| --- | --- |
| `searchUrls` | Required array of 1–10 exact HTTPS Naver Map search URLs. Each path must contain Korean text. Only the optional `c` viewport parameter is supported. |
| `maxItems` | Global maximum unique businesses, default 20, range 1–200. Zero and unlimited are unsupported. |

Duplicate URLs are processed once. Businesses are deduplicated across searches by place ID; the first occurrence supplies provenance. Earlier URLs can consume the entire limit. Only the first result page from each search is collected, so increasing the limit does not enable pagination.

The URL query is sent unchanged to Naver. Relevance, synonyms, proximity and ordering are controlled by Naver, not an exact business-name matcher. A location keyword or viewport is not a guaranteed geographic boundary; validate addresses before using results as an area census.

### Extracted data

| Fields | Description |
| --- | --- |
| `placeId`, `name` | Stable Naver identity and public name. |
| `categories` | Source category hierarchy, an array of strings. |
| `telephone` | Public business telephone, possibly a Naver forwarding number. |
| `homepage` | Homepage or social URL shown in search. |
| `address`, `roadAddress` | Lot-based and road-name addresses. |
| `latitude`, `longitude` | Numeric coordinates. |
| `reviewCount`, `placeReviewCount` | Two source counters; no individual reviews are extracted. |
| `hasNaverBooking` | Booking flag exposed in the listing, not live inventory. |
| `placeUrl` | Canonical mobile Place home URL. |
| `sourceUrl`, `query`, `scrapedAt` | Search provenance and UTC extraction timestamp. |

Missing optional text and numeric values are null; categories may be empty. Counters are source values and need not agree. Missing booking flags normalize to false; this is not proof that a business never accepts reservations.

### Output example

A representative public business observed during testing:

```json
{
  "placeId": "1789177874",
  "name": "신이도가",
  "categories": ["음식점", "카페,디저트"],
  "telephone": "0507-1411-3461",
  "homepage": "https://www.instagram.com/shinleedoga",
  "address": "서울특별시 마포구 서교동 367-31 1층 신이도가",
  "roadAddress": "서울특별시 마포구 잔다리로 20-12 1층 신이도가",
  "latitude": 37.5514492,
  "longitude": 126.9209447,
  "reviewCount": 795,
  "placeReviewCount": 1432,
  "hasNaverBooking": false,
  "placeUrl": "https://m.place.naver.com/place/1789177874/home",
  "sourceUrl": "https://map.naver.com/p/search/서울%20카페",
  "query": "서울 카페",
  "scrapedAt": "2026-10-17T20:04:53.074Z"
}
```

The homepage query string is shortened in this illustration. Actual output preserves the source homepage.

### How much does it cost to extract Naver local businesses?

Pricing is pay per event: one `start` fee per valid run plus one `item` event per business saved. No separate event is charged for contact fields or review counts. Pricing is $0.005 per start and $0.0014 per business at BRONZE. At these prices 1, 20 and 100 businesses cost $0.0064, $0.033 and $0.145. Other subscription tiers have different item rates.

A valid run that encounters a source challenge may still incur the start fee. Invalid inputs are rejected before charging. Source or billing limits can produce fewer rows than requested. Check the Pricing tab before running.

### Limits and reliability

Korean residential proxy and Chromium sessions are built in; no Naver login or private cookies are needed. Searches run sequentially. A stalled initial search has a 15-second navigation/response window, then receives at most one retry with a fresh browser and proxy identity and a 90-second window for slower searches. The windows include response-body consumption; browser startup and cleanup add time outside them. Images, media and fonts are blocked to reduce transfer.

Challenges, unrecognized responses and malformed businesses cause failure rather than misleading empty success. A recognized empty business list yields no rows. A later failed search can leave partial data from earlier searches: inspect run status before treating a dataset as complete.

This Actor does not extract review text, personal-contact enrichment, menus, photos, opening hours, detail pages, booking inventory, exhaustive pages, historical snapshots or built-in change alerts. No CAPTCHA solving or signed-in access is supported.

### Integrations

Schedule recurring runs with Apify schedules. Join exports by `placeId` in your database or spreadsheet to compare snapshots externally. Use webhooks to send successful-run notifications to Make, Zapier or your ETL pipeline. These integrations do not add built-in history or alerts to the Actor.

The run's `SUMMARY` key-value record reports saved businesses, completed searches and session attempts. Its observed byte counter covers only response Content-Length headers and is not a billing-transfer measure.

### API usage

Use a token with access to the Actor. Never publish your token.

```bash
curl -X POST "https://api.apify.com/v2/acts/automation-lab~naver-map-business-scraper/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchUrls":["https://map.naver.com/p/search/서울%20카페"],"maxItems":20}'
```

JavaScript using `apify-client`:

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/naver-map-business-scraper').call({
  searchUrls: ['https://map.naver.com/p/search/서울%20카페'], maxItems: 20
});
const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 20 });
console.log(items);
```

Python using `apify-client`:

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/naver-map-business-scraper').call(
    run_input={'searchUrls': ['https://map.naver.com/p/search/서울%20카페'], 'maxItems': 20})
items = client.dataset(run['defaultDatasetId']).list_items(limit=20).items
print(items)
```

### MCP usage

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/naver-map-business-scraper"
```

Claude Desktop, Cursor, and VS Code setup (use each client's HTTP MCP configuration):

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/naver-map-business-scraper"}}}
```

Authenticate as required by your client. Discover actual tool names and argument schemas with `tools/list`; Actor selection also exposes run/data helper tools, not exactly one tool. Discovery does not authorize execution.

Example prompt: “Snapshot up to 20 businesses from this Korean Naver Map search URL, then summarize names and addresses.” For an authorized invocation, start once and retain the returned run ID and storage IDs. These IDs are metadata, not business results. If nonterminal, follow the same run using `get-actor-run` with bounded 2/4/8-second backoff, capped at 10 seconds and a 120-second total deadline. Configure transport timeout above the selected server wait. On timeout recover the known run instead of starting another; at deadline report pending and stop.

After success, fetch the returned dataset with `get-dataset-items`: pages of 20 source rows, explicit offset and needed fields, at most 100 rows or 64 KiB of serialized UTF-8 content admitted to model context. Enforce bytes host-side, including oversized rows, before model injection; if your client cannot intercept responses, do not claim a hard byte guarantee. Track source offsets, disclose partial/truncated results and leave full exports in storage. Report terminal failures honestly and treat existing rows as partial.

### Legality and responsible use

Use public business data responsibly and comply with applicable laws, source terms and privacy obligations. Public availability does not authorize spam or unrestricted reuse. This Actor does not provide legal advice and is not affiliated with Naver.

No AI model processes your inputs or business records. Apify runs and stores the results; its KR residential proxy routes public Naver requests. Company-paid compute, proxy and storage costs are covered by the stated event prices, with no external service account required.

Browser cookies and sessions are ephemeral and discarded when the browser closes. Datasets, input, summary and logs use your Apify storage retention (31 days on our current plan; your workspace policies may differ). Delete run storage through Apify when no longer needed. Logs contain counters and bounded failure reasons, not raw source responses or proxy credentials. For support use the Actor's Issues tab; do not post secrets.

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL query strings are removed; reports are retained for 30 days. Do not include private information in search URLs.

### FAQ

**Why fewer rows than maxItems?** Only the first business-result page is collected. Sparse searches, duplicate businesses or billing limits can reduce the count.

**Can I use English or direct Place URLs?** No. This contract requires exact Korean Map search URLs, not Place detail IDs or English queries.

**Why did a search fail?** A challenge, unsupported search shape or temporary session failure can exhaust both attempts. Check the log and retry later; do not interpret a failed run as an empty market.

**Does it enforce city boundaries?** No. Naver controls the search results. Use exported addresses or coordinates for your own geographic validation.

### Related Actor

For review text from known Place IDs, use [Naver Reviews Scraper](https://apify.com/automation-lab/naver-place-business-reviews-scraper). That is a separate downstream workflow, not included here.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/naver-map-business-scraper/changelog.md

# Actor input Schema

## `searchUrls` (type: `array`):

1–10 exact https://map.naver.com/p/search/<query> URLs containing a Korean keyword and location. The query is sent unchanged to Naver; Naver controls relevance, not an exact-name matcher. Only the optional c viewport query parameter is accepted. Duplicate URLs are processed once in input order. First page only; businesses are deduplicated globally by place ID.

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

Global limit after place-ID deduplication across all URLs, processed in order. Default 20; range 1–200. Zero and unlimited are not supported. Stops early at the limit; fewer rows are possible because only each search's first page is read. A billing cap may stop output earlier.

## Actor input object example

```json
{
  "searchUrls": [
    "https://map.naver.com/p/search/%EC%84%9C%EC%9A%B8%20%EC%B9%B4%ED%8E%98?c=126.97825,37.566551,13,0,0,0,dh"
  ],
  "maxItems": 20
}
```

# Actor output Schema

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

Deduplicated public first-page business records.

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

Search and session counters.

# 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 = {
    "searchUrls": [
        "https://map.naver.com/p/search/%EC%84%9C%EC%9A%B8%20%EC%B9%B4%ED%8E%98?c=126.97825,37.566551,13,0,0,0,dh"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/naver-map-business-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 = {
    "searchUrls": ["https://map.naver.com/p/search/%EC%84%9C%EC%9A%B8%20%EC%B9%B4%ED%8E%98?c=126.97825,37.566551,13,0,0,0,dh"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/naver-map-business-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 '{
  "searchUrls": [
    "https://map.naver.com/p/search/%EC%84%9C%EC%9A%B8%20%EC%B9%B4%ED%8E%98?c=126.97825,37.566551,13,0,0,0,dh"
  ],
  "maxItems": 20
}' |
apify call automation-lab/naver-map-business-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/naver-map-business-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/4zdT99BTrSNpoFX2g/builds/lCvvTNTaKx2LNRTUI/openapi.json
