# Naver Place Visitor & Blog Review Finder (`dataspryva/naver-place-visitor-and-blog-review-finder`) Actor

Collect Naver Place visitor reviews, linked Naver Blog posts, and aggregated rating statistics by place URL/ID or keyword search, with ratings, voted keywords, photos and owner replies.

- **URL**: https://apify.com/dataspryva/naver-place-visitor-and-blog-review-finder.md
- **Developed by:** [Dataspryva](https://apify.com/dataspryva) (community)
- **Categories:** Automation, Lead generation, Travel
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 Place Visitor & Blog Review Finder

Naver Place is where most South Koreans check reviews before visiting a restaurant, cafe, clinic, or shop. This actor collects visitor reviews, linked Naver Blog posts, and aggregated rating statistics by place URL/ID or keyword search.

### What this actor does

- **Visitor reviews at scale** — text reviews and rating-only reviews from Naver's separate review streams, paginated 50 per request up to your `maxReviews` cap (1–5,000 per place)
- **Exact dates** — review creation date and timestamp, visit date, and blog publish date, including reviews older than one year
- **Blog and cafe reviews** — linked Naver Blog posts with title, excerpt, author, thumbnails, source type, and publish date, up to Naver's 100-per-place cap
- **Aggregated statistics** — average rating, half-star distribution, review themes, top menus, voted-keyword counts, image/author counts, and text vs rating-only totals
- **Two start modes** — give place URLs/IDs (including `naver.me` short links), search by keyword, or combine both
- **Incremental runs** — filter by visit date and exclude known review IDs or blog URLs
- **Clean records** — empty fields are omitted instead of returned as null

### Output per record

Every record has a `reviewType` of `visitor`, `blog`, or `stats`.

#### Visitor review (`reviewType: "visitor"`)

- `placeId`, `placeName`, `placeCategory`, `placeBusinessCategory`, `placeAddress`, `placeRoadAddress`, `placeRating`, `placeTotalReviews`, `placeBlogReviewCount`, `placeUrl` — place identity
- `searchKeyword`, `searchRank` — keyword that found the place and its search rank
- `reviewId`, `reviewText`, `reviewHasText`, `reviewRating` — the review itself; `reviewHasText` is false for rating-only rows, and `reviewRating` is omitted when Naver withholds it on older reviews
- `reviewDate`, `reviewCreatedAt`, `visitDate`, `visitCount`, `visitCountLabel` — when it was posted, when the visit happened, and how many visits the reviewer reports
- `reviewerName`, `reviewerProfileUrl`, `reviewerImageUrl`, `reviewerFollowerCount`, `reviewerReviewCount`, `reviewerAverageRating` — reviewer identity and stats
- `votedKeywords[]`, `visitTags[]` — Naver's official review-vote tags and visit-context tags
- `reviewPhotos[]`, `mediaCount` — photo and video-thumbnail URLs (when `includeReviewPhotos` is enabled) and the total media count
- `reviewReplyText`, `reviewReplyDate`, `hasReply`, `replyStatus` — the owner's reply
- `menuItem`, `originType`, `language`, `translatedText`, `reviewReactionCount`, `reviewViewCount` — review context
- `scrapedAt` — ISO 8601 timestamp

#### Blog review (`reviewType: "blog"`)

- Place identity and `searchKeyword`/`searchRank`, same as above
- `blogTitle`, `blogContents`, `blogContentsLength`, `blogUrl` — post title, excerpt, excerpt length, and link
- `bloggerName`, `bloggerHome`, `bloggerProfileImageUrl` — blogger identity
- `blogDate`, `blogSource`, `blogTypeName` — publish date, source type (`blog` or `cafe`), and localized label
- `blogRank`, `isRepresentative`, `isSelfPaid` — position, representative flag, and self-paid flag
- `blogThumbnailUrl`, `blogThumbnailUrls[]` — primary thumbnail and all thumbnails
- `scrapedAt` — ISO 8601 timestamp

#### Stats (`reviewType: "stats"`, one per place)

- Place identity and `searchKeyword`/`searchRank`
- `averageRating`, `totalReviewCount`, `starDistribution`, `ratingDistribution` — average, total, integer histogram when available, and the exact half-star histogram
- `reviewThemes[]`, `topMenus[]`, `votedKeywordStats[]` — theme labels, most-mentioned menu items, and voted-keyword counts
- `imageReviewCount`, `authorCount`, `totalVisitorReviews`, `textReviewCount`, `ratingReviewCount`, `blogReviewCount` — review counts
- `scrapedVisitorReviews`, `scrapedBlogReviews`, `runRatingDistribution`, `runKeywordDistribution` — what this run collected for the place
- `scrapedAt` — ISO 8601 timestamp

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `placeUrls` | array | – | Naver Place URLs, `naver.me` links, or bare numeric place IDs |
| `searchKeywords` | array | – | Keywords to discover places first; can be combined with `placeUrls` |
| `maxPlacesPerKeyword` | integer | `3` | Places per keyword (1–100; Naver returns up to 100) |
| `maxReviews` | integer | `100` | Visitor reviews per place across both streams (1–5,000) |
| `includeVisitorReviews` | boolean | `true` | Collect visitor reviews |
| `includeRatingOnlyReviews` | boolean | `true` | Also collect rating-only reviews from the separate stream |
| `includeBlogReviews` | boolean | `true` | Collect linked blog and cafe posts |
| `maxBlogReviews` | integer | `100` | Blog posts per place (1–100; Naver's hard cap) |
| `includeReviewPhotos` | boolean | `false` | Include review photo and video-thumbnail URLs |
| `includeReviewStats` | boolean | `true` | Emit one stats record per place |
| `visitedSince` | date | – | Keep only reviews with a visit date on or after this date |
| `excludeReviewIds` | array | – | Visitor review IDs and blog URLs to skip |
| `maxConcurrency` | integer | `3` | Places scraped in parallel (1–10) |
| `maxItems` | integer | `100` | Hard cap on total records across all places (1–5,000) |
| `proxyConfiguration` | object | – | Optional proxy; direct requests are tried first and an Apify datacenter proxy is used only after a real block |

#### Example: reviews for specific places

```json
{
  "placeUrls": [
    "https://map.naver.com/p/entry/place/38239053",
    "1000750444"
  ],
  "maxReviews": 500,
  "includeRatingOnlyReviews": true,
  "includeReviewPhotos": true,
  "includeReviewStats": true,
  "maxItems": 1000
}
```

#### Example: discover places by keyword first

```json
{
  "searchKeywords": ["강남 맛집", "홍대 카페"],
  "maxPlacesPerKeyword": 10,
  "maxReviews": 100,
  "includeBlogReviews": true,
  "maxBlogReviews": 20,
  "includeReviewStats": true,
  "maxItems": 2000
}
```

#### Example: only new reviews since a date

```json
{
  "placeUrls": ["38239053"],
  "visitedSince": "2026-09-01",
  "excludeReviewIds": ["6abf13296171f06ddbf56400"],
  "maxReviews": 200
}
```

### Use cases

- **Market entry research** — read what local customers actually say about a category or area before entering the Korean market
- **Restaurant and cafe competitive analysis** — compare ratings, rating distributions, voted keywords, and review volume across nearby competitors
- **Customer sentiment tracking** — build a structured, NLP-ready archive of Korean-language reviews with exact dates and visit context
- **Brand reputation monitoring** — track voted keywords, owner replies, and review themes for your own listed business
- **Academic research** — study Korean consumer review behavior at scale, including rating-only reviews and blog coverage

### FAQ

**Is this affiliated with Naver?**
No. This is an independent, third-party actor that reads publicly available Naver Place pages and Naver's public review endpoints. It isn't operated by or affiliated with Naver.

**Do I need a Naver login, cookie, or API key?**
No. The actor uses public, cookieless endpoints. No login, cookie, or API key is required.

**How many visitor reviews can I get per place?**
Up to 5,000 per place with `maxReviews`. Naver paginates 50 reviews per request, and the actor follows the cursor until your cap or the end of the review stream. `maxReviews` counts both text reviews and rating-only reviews.

**What are rating-only reviews?**
Some visitors leave a star rating without writing text. Naver serves those from a separate stream. Enable `includeRatingOnlyReviews` to include them; `reviewHasText` is false on those rows.

**Why do some visitor reviews have no star rating?**
Naver returns individual star ratings only for its newest reviews on anonymous requests; older reviews in the same cursor stream come back with no rating. The actor omits the field rather than guessing. Text, dates, reviewer, tags, photos, and replies still fill normally, and the stats record's `ratingDistribution` covers every rating Naver reports for the place.

**Why is `blogDate` now filled?**
The blog/cafe review endpoint returns an exact publish date (`YYYY.MM.DD.`). The actor normalizes it to `YYYY-MM-DD`. Blog posts are still capped at 100 per place by Naver.

**Why are some stats fields missing for a place?**
Naver doesn't track an average rating, star distribution, themes, or menus for every vertical. Cafes and some clinics often have no average or histogram. Unavailable fields are omitted rather than guessed.

**How exact are review dates?**
Review creation dates come from Naver's review ID timestamp, converted to Korea Standard Time, with the displayed date as a fallback. This fixes the wrong-year dates that short display strings like `21.10.21.목` used to produce. Visit dates come from Naver's exact visit-date field.

**Why might `reviewPhotos` be empty even with `includeReviewPhotos` enabled?**
Not every review has photos or video. `mediaCount` tells you how many media items the review has; `reviewPhotos` is only populated when the review actually has media.

**Do I need a proxy?**
No. The actor tries direct requests first and automatically escalates to an Apify datacenter proxy only if Naver blocks the request. You can supply your own proxy configuration if you prefer.

**How fresh is the data?**
Each run reads Naver's current review endpoints, so review counts and content reflect what is published at run time. Naver's totals can drift slightly between requests because new reviews arrive continuously.

# Actor input Schema

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

Naver Place URLs, naver.me short links, or bare numeric Place IDs. Examples: 'https://map.naver.com/p/entry/place/38239053', 'https://pcmap.place.naver.com/place/38239053/home', '38239053'.

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

Keywords to discover places first, then scrape their reviews. Example: \['강남 맛집', '홍대 카페']. Can be combined with placeUrls.

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

Maximum places to scrape per keyword search. Naver's search page returns up to 100 places per keyword.

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

Maximum visitor reviews to collect per place, across both the text-review stream and the rating-only stream. Naver paginates 50 reviews per request.

## `includeVisitorReviews` (type: `boolean`):

Collect visitor reviews. Turn off for a blog-only or stats-only run.

## `includeRatingOnlyReviews` (type: `boolean`):

Also collect reviews that have a star rating but no written text. These come from a separate Naver review stream and count toward maxReviews.

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

Collect Naver Blog and cafe posts linked to the place, with exact publish dates.

## `maxBlogReviews` (type: `integer`):

Maximum linked blog/cafe posts per place. Naver exposes at most 100 per place.

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

Include photo and video-thumbnail URLs attached to each visitor review.

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

Emit one stats record per place: average rating, rating distribution, themes, top menus, voted keywords, and review counts.

## `visitedSince` (type: `string`):

Only keep visitor reviews whose visit date is on or after this date. Reviews without a visit date are skipped when this filter is set.

## `excludeReviewIds` (type: `array`):

Visitor review IDs and blog post URLs to skip. Useful for incremental runs that only want new reviews.

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

How many places to scrape in parallel. Higher is faster but increases rate-limit risk.

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

Hard cap on total records emitted across all places.

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

Optional. Leave empty to use direct requests; the actor escalates to an Apify datacenter proxy only after a real block.

## Actor input object example

```json
{
  "placeUrls": [
    "https://map.naver.com/p/entry/place/38239053"
  ],
  "maxPlacesPerKeyword": 3,
  "maxReviews": 3,
  "includeVisitorReviews": true,
  "includeRatingOnlyReviews": false,
  "includeBlogReviews": false,
  "maxBlogReviews": 10,
  "includeReviewPhotos": false,
  "includeReviewStats": false,
  "maxConcurrency": 3,
  "maxItems": 3
}
```

# Actor output Schema

## `reviews` (type: `string`):

Dataset containing visitor reviews, blog reviews, and place review statistics.

# 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 = {
    "placeUrls": [
        "https://map.naver.com/p/entry/place/38239053"
    ],
    "maxPlacesPerKeyword": 3,
    "maxReviews": 3,
    "includeVisitorReviews": true,
    "includeRatingOnlyReviews": false,
    "includeBlogReviews": false,
    "maxBlogReviews": 10,
    "includeReviewPhotos": false,
    "includeReviewStats": false,
    "maxConcurrency": 3,
    "maxItems": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataspryva/naver-place-visitor-and-blog-review-finder").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 = {
    "placeUrls": ["https://map.naver.com/p/entry/place/38239053"],
    "maxPlacesPerKeyword": 3,
    "maxReviews": 3,
    "includeVisitorReviews": True,
    "includeRatingOnlyReviews": False,
    "includeBlogReviews": False,
    "maxBlogReviews": 10,
    "includeReviewPhotos": False,
    "includeReviewStats": False,
    "maxConcurrency": 3,
    "maxItems": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("dataspryva/naver-place-visitor-and-blog-review-finder").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 '{
  "placeUrls": [
    "https://map.naver.com/p/entry/place/38239053"
  ],
  "maxPlacesPerKeyword": 3,
  "maxReviews": 3,
  "includeVisitorReviews": true,
  "includeRatingOnlyReviews": false,
  "includeBlogReviews": false,
  "maxBlogReviews": 10,
  "includeReviewPhotos": false,
  "includeReviewStats": false,
  "maxConcurrency": 3,
  "maxItems": 3
}' |
apify call dataspryva/naver-place-visitor-and-blog-review-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataspryva/naver-place-visitor-and-blog-review-finder"
        }
    }
}
```

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/YRhCBuZlgIYwIEIUT/builds/pizAoyiv3kJIJ7ul8/openapi.json
