# Naver Place Review Scraper — Visitor & Blog Reviews (`memo23/naver-place-review-scraper`) Actor

Naver Place Review Scraper for Korean businesses: search Naver Map by keyword or paste place links and get visitor reviews with stars, visit date, voted keywords and owner reply, plus Naver Blog and Cafe posts and a rating summary per place. Newest first, JSON or CSV.

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

## Pricing

from $0.69 / 1,000 review scrapeds

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

Reviews of Korean shops, restaurants, clinics and sights live on Naver Map, not Google. This actor reads them for you: give it a few Naver Map searches or place links, and it returns each place's visitor reviews, the Naver Blog and Cafe posts written about it, and a one-row rating summary, as a table you can export to JSON, CSV or Excel.

### What it collects

- **Visitor reviews**: the text, the star score, when it was written and when the visit was, how many times the reviewer has been, the keywords they ticked ("음식이 맛있어요"), and the owner's reply with its date.
- **Reviewer context**: nickname, profile link, how many reviews they have written and their average score, so you can tell regulars from one-off accounts.
- **Blog and Cafe posts**: title, text excerpt, link, author and date for the posts Naver attaches to the place.
- **A rating summary per place**: average score, how many reviews gave each score, and the keywords visitors voted for most.
- **Photos when you want them**: every review row has a photo count; switch photos on to also get the image links.

### Two ways to pick places

| Give it | Example | What happens |
|---|---|---|
| A Naver Map search | `강남 맛집`, `홍대 카페`, `Seoul BBQ` | The top places for that search are taken (5 by default) |
| A place link | `https://map.naver.com/p/entry/place/11571707` | That place is scraped |
| A place ID | `11571707` | Same as the link |

Links from `map.naver.com`, `pcmap.place.naver.com`, `m.place.naver.com` and `place.naver.com` all work. `naver.me` short links do not, because the ID only appears after a redirect: open the short link in a browser and paste the full address instead. Searches and links can be combined in one run; a place found twice is scraped once.

Naver Shopping product reviews and Naver Blog search results are separate services and are not covered here.

### Who uses it

Restaurant and clinic groups watching what visitors say at each branch. Agencies doing Korean local SEO, who need the voted keywords. Tourism teams tracking sentiment at landmarks. Researchers and NLP teams who need Korean review text with star labels.

### How a run goes

![How the Naver Place Review Scraper works](https://api.apify.com/v2/key-value-stores/cLPT29TLknd4AP8aJ/records/how-it-works-naver-place.png)

Searches go through Naver Map's own search box endpoint and return place IDs. For each place the actor then asks Naver's place service for the name, category, address and totals, reads visitor reviews 50 at a time in the order you chose until it hits your limit or the place runs out, adds the blog posts from the place page, and finally the rating summary. Places are worked on in parallel (5 at a time by default) and each place's rows are saved together when it finishes.

### Settings

In the order of the input form:

| Field | Default | Meaning |
|---|---|---|
| `searchKeywords` | none | Naver Map searches, one per line |
| `maxPlacesPerKeyword` | 5 | Top results kept per search, 1 to 50 |
| `placeUrls` | demo place | Place links or numeric IDs |
| `includeReviewStats` | on | One rating-summary row per place |
| `includeBlogReviews` | on | Blog and Cafe post rows |
| `maxBlogReviewPages` | 10 | Blog posts kept per place, in tens |
| `reviewSort` | `NEWEST` | `NEWEST` or `RANKING` (Naver's default order) |
| `maxReviewPages` | 1 | Visitor reviews per place, in fifties |
| `maxReviews` | none | Exact visitor review cap; replaces the page count when set |
| `includeReviewPhotos` | off | Image links on visitor reviews |
| `maxConcurrency` | 5 | Places scraped at once, 1 to 10 |
| `proxy` | Apify residential | Naver throttles datacenter IPs |

#### Sample inputs

The 100 newest reviews of one place, nothing else:

```json
{
  "placeUrls": ["11571707"],
  "maxReviews": 100,
  "includeBlogReviews": false,
  "includeReviewStats": false
}
```

Rating summary and the latest 50 reviews for the top 10 Gangnam restaurants:

```json
{
  "searchKeywords": ["강남 맛집"],
  "maxPlacesPerKeyword": 10,
  "maxReviewPages": 1
}
```

Two places with photo links and blog posts:

```json
{
  "placeUrls": ["11571707", "https://map.naver.com/p/entry/place/38345004"],
  "maxReviewPages": 4,
  "includeReviewPhotos": true,
  "maxBlogReviewPages": 3
}
```

### What comes back

Every row has a `reviewType`:

- `visitor`: one visitor review
- `blog`: one Naver Blog or Cafe post
- `place_stats`: the rating summary of one place

Each row also repeats the place it belongs to (ID, name, category, address, average score, total review count and link), so any single row can be read on its own and rows from many places can share one sheet.

Real rows from a run on Gyeongbokgung Palace, shortened:

```json
{
  "placeName": "경복궁",
  "reviewType": "visitor",
  "reviewRating": 5,
  "reviewDate": "10.21.수",
  "reviewText": "한한령 중국 한국 여행 금지 풀렸나 봐요...",
  "votedKeywords": ["사진이 잘 나와요", "볼거리가 많아요", "방문객이 많아요", "규모가 커요"],
  "visitDate": "10.21.수",
  "visitCount": 2,
  "reviewPhotoCount": 14,
  "reviewId": "6ad874ae656738da5f4c1e6c",
  "reviewerName": "백수인",
  "placeCategory": "궁궐",
  "placeAddress": "서울 종로구 사직로 161 경복궁",
  "placeRating": 4.69,
  "placeTotalReviews": 12539,
  "placeId": "11571707",
  "placeUrl": "https://pcmap.place.naver.com/place/11571707"
}
```

```json
{
  "placeName": "경복궁",
  "reviewType": "blog",
  "blogTitle": "아이와 서촌산책코스 | 경복궁 은행나무...",
  "blogUrl": "https://m.blog.naver.com/ssongji337/224448694403",
  "blogType": "블로그",
  "bloggerName": "랑새",
  "blogDate": "2일 전",
  "placeId": "11571707"
}
```

```json
{
  "placeName": "YTN서울타워",
  "reviewType": "place_stats",
  "averageRating": 4.47,
  "starDistribution": [
    { "score": null, "count": 1 },
    { "score": 2.5, "count": 2 },
    { "score": 3, "count": 12 },
    { "score": 3.5, "count": 10 },
    { "score": 4, "count": 27 },
    { "score": 4.5, "count": 16 },
    { "score": 5, "count": 88 }
  ],
  "placeId": "38345004"
}
```

Dates are kept the way Naver prints them (`10.21.수` is 21 October, a Wednesday; `2일 전` is two days ago).

#### Field groups

- **The place:** `placeId`, `placeName`, `placeCategory`, `placeAddress`, `placeRating`, `placeTotalReviews`, `placeUrl`
- **The visitor review:** `reviewId`, `reviewText`, `reviewRating`, `reviewDate`, `visitDate`, `visitCount`, `votedKeywords`, `visitCategories`, `reviewTags`, `reviewPhotoCount`, `reviewPhotos`
- **The reviewer:** `reviewerName`, `reviewerProfileUrl`, `reviewerImageUrl`, `reviewerReviewCount`, `reviewerAvgRating`
- **The owner's answer:** `reviewReplyText`, `reviewReplyDate`
- **The blog post:** `blogTitle`, `blogContents`, `blogUrl`, `blogType`, `bloggerName`, `blogDate`, `blogThumbnailUrl`
- **The summary:** `averageRating`, `starDistribution`, `topVotedKeywords`
- **The run:** `scrapedAt`

Fields that do not apply to a row type are `null` (a blog row has no star score).

`starDistribution` counts the rated reviews per half-star score (0.5 to 5), lowest first; reviews left without stars are not in it. Naver sends these counts without their scores and drops the scores nobody gave, so the actor works the scores out from Naver's own average. A bucket it cannot place for certain keeps `score: null`; that happens only to small buckets at the low end, like the single review above.

### Billing and the free plan

One `review-scraped` event per visitor row and per blog row. Rating-summary rows are free. If the run reaches your spending limit it stops reading new reviews and saves what it has.

On Apify's free plan a run keeps up to 10 visitor reviews and one page of blog posts per place, and takes 2 places per search.

### Questions

**Do I need a proxy?**
A place or two works without one. Past that, Naver starts refusing requests from a single IP, which is why the default is Apify's residential proxy.

**Pages or an exact number?**
`maxReviewPages` counts in fifties and is the simple choice. Set `maxReviews` when you need an exact number such as 120; it then replaces the page count.

**Why fewer visitor reviews than the place's review count?**
The actor reads every review in Naver's review list, up to your limit. That list can be shorter than the counter on the place page: for N Seoul Tower the counter said 510 and the list held 416 on 24 Oct 2026. Naver does not list the rest.

**Why fewer blog posts than Naver's total?**
The actor takes the posts Naver shows on the place page. For places with thousands of posts that is a limited batch, not the full archive.

**Can I get English reviews?**
Reviews come in the language the visitor wrote, almost always Korean. Voted keywords are fixed Korean phrases Naver offers to every reviewer.

**Why did a link get skipped?**
It was a `naver.me` short link or a page that is not a place (a search result list, a blog). The run log names each skipped line.

### Support

- [Issues tab of this actor](https://console.apify.com/actors/HF1y2OzTqrjF8Yq4x/issues)
- Website: [muhamed-didovic.github.io](https://muhamed-didovic.github.io)
- Email: muhamed.didovic@gmail.com

### Additional Services

Need a recurring export, a filter the actor does not have, or a one-off dataset of Naver Place reviews? Write to muhamed.didovic@gmail.com.

### Explore More Scrapers

More actors for real estate, jobs, B2B data, social media and e-commerce: [muhamed-didovic.github.io](https://muhamed-didovic.github.io).

### 🤖 For AI Agents & LLM Apps

`memo23/naver-place-review-scraper` returns Naver Map (네이버 플레이스) visitor reviews, blog posts and rating summaries for Korean businesses.

Minimal input:

```json
{ "placeUrls": ["11571707"], "maxReviews": 20 }
```

- Input: `placeUrls` (links or numeric IDs) and/or `searchKeywords` (Naver Map searches).
- Rows: `reviewType` is `visitor`, `blog` or `place_stats`; every row carries `placeId` and `placeName`.
- Main visitor fields: `reviewText`, `reviewRating`, `reviewDate`, `visitDate`, `votedKeywords`, `reviewReplyText`.
- Billing: one event per visitor or blog row; summary rows free. Free plan: 10 reviews per place.

### ⚠️ Disclaimer

This actor is independent and is not made, endorsed or sponsored by NAVER Corporation. Naver and Naver Place are trademarks of NAVER Corporation. The actor reads publicly visible review data. Reviewer nicknames and profile links are personal data under Korea's Personal Information Protection Act (PIPA) and the GDPR; you are responsible for having a legal basis to collect and use them, and for following Naver's terms.

### SEO Keywords

naver place scraper, naver place review scraper, naver map reviews, 네이버 플레이스 리뷰, 네이버 지도 리뷰 크롤링, korean review scraper, naver visitor reviews export, naver blog reviews, naver cafe posts, korean local business reviews, naver rating summary, naver voted keywords, korean restaurant reviews, gangnam restaurant reviews, korean local seo, naver review sentiment, korean review dataset, naver map data export

# Actor input Schema

## `searchKeywords` (type: `array`):

What you would type into Naver Map's search box, one search per line, e.g. 강남 맛집 or 홍대 카페. The top places for each search are added to the run (see Places per keyword). Leave empty to use only the place links below.

## `maxPlacesPerKeyword` (type: `integer`):

How many of the top results to take from each keyword search, 1-50. Default 5. Runs on Apify's free plan take 2.

## `placeUrls` (type: `array`):

One place per line: a link from map.naver.com (/p/entry/place/<id>), pcmap.place.naver.com, m.place.naver.com or place.naver.com, or just the numeric place ID, e.g. 11571707. naver.me short links are skipped because they hide the ID; open them once and copy the full link. With no links and no keywords the actor runs on Gyeongbokgung Palace (11571707) as a demo.

## `includeReviewStats` (type: `boolean`):

On (default): one extra row per place (reviewType place_stats) with the average rating, how many reviews gave each half-star score, and the keywords visitors voted for most. Summary rows are not billed.

## `includeBlogReviews` (type: `boolean`):

On (default): also returns the Naver Blog and Naver Cafe posts that Naver lists on each place, one row each (reviewType blog) with title, text, link, author and date. Each post row is billed like a visitor review.

## `maxBlogReviewPages` (type: `integer`):

Caps the blog posts kept per place in pages of 10, 1-100: 2 keeps up to 20 posts. Default 10. Naver itself only lists a limited number of posts per place. Runs on Apify's free plan keep 1 page.

## `reviewSort` (type: `string`):

NEWEST (default): most recent reviews first, the right choice for monitoring. RANKING: the order Naver shows a visitor by default. Matters when you cap the count, because the cap keeps the first reviews in this order.

## `maxReviewPages` (type: `integer`):

Visitor reviews are read 50 at a time. 1 page is about 50 reviews per place, 20 pages about 1,000. Reading stops early when a place runs out. Default 1. Not used when Visitor reviews per place is set. Runs on Apify's free plan read 1 page.

## `maxReviews` (type: `integer`):

An exact number of visitor reviews per place, e.g. 120, instead of whole pages. When set, it replaces the page count above. Empty (default): the page count decides. Runs on Apify's free plan stop at 10.

## `includeReviewPhotos` (type: `boolean`):

Off (default): each visitor review row has reviewPhotoCount only. On: reviewPhotos also lists the URLs of the images the visitor attached.

## `maxConcurrency` (type: `integer`):

How many places are scraped at the same time, 1-10. Default 5. Higher finishes long lists sooner; Naver is more likely to refuse requests at high values without a residential proxy.

## `proxy` (type: `object`):

Default: Apify Proxy. When no proxy group is picked, the actor uses the residential group, because Naver throttles datacenter traffic. You can choose another group or enter your own proxy URLs.

## Actor input object example

```json
{
  "searchKeywords": [],
  "maxPlacesPerKeyword": 2,
  "placeUrls": [
    "https://map.naver.com/p/entry/place/38345004"
  ],
  "includeReviewStats": true,
  "includeBlogReviews": true,
  "maxBlogReviewPages": 1,
  "reviewSort": "NEWEST",
  "maxReviewPages": 1,
  "includeReviewPhotos": false,
  "maxConcurrency": 5,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

# 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 = {
    "searchKeywords": [],
    "maxPlacesPerKeyword": 2,
    "placeUrls": [
        "https://map.naver.com/p/entry/place/38345004"
    ],
    "maxBlogReviewPages": 1,
    "maxReviewPages": 1,
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/naver-place-review-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 = {
    "searchKeywords": [],
    "maxPlacesPerKeyword": 2,
    "placeUrls": ["https://map.naver.com/p/entry/place/38345004"],
    "maxBlogReviewPages": 1,
    "maxReviewPages": 1,
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/naver-place-review-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 '{
  "searchKeywords": [],
  "maxPlacesPerKeyword": 2,
  "placeUrls": [
    "https://map.naver.com/p/entry/place/38345004"
  ],
  "maxBlogReviewPages": 1,
  "maxReviewPages": 1,
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call memo23/naver-place-review-scraper --silent --output-dataset

```

## MCP server setup

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