Use Naver Place Visitor & Blog Review Finder with Python
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.
1. Choose the data you need
Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.
2. Prepare a source-based input
This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.
{
"includeBlogReviews": false,
"includeRatingOnlyReviews": false,
"includeReviewPhotos": false,
"includeReviewStats": false,
"includeVisitorReviews": true,
"maxBlogReviews": 10,
"maxConcurrency": 3,
"maxItems": 3,
"maxPlacesPerKeyword": 3,
"maxReviews": 3,
"placeUrls": [
"https://map.naver.com/p/entry/place/38239053"
]
}
Download input.example.json and save your reviewed copy as input.json.
| Field | Type | Required | Description |
|---|---|---|---|
placeUrls | array | optional | 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 | array | optional | Keywords to discover places first, then scrape their reviews. Example: ['강남 맛집', '홍대 카페']. Can be combined with placeUrls. |
maxPlacesPerKeyword | integer | optional | Maximum places to scrape per keyword search. Naver's search page returns up to 100 places per keyword. |
maxReviews | integer | optional | 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 | boolean | optional | Collect visitor reviews. Turn off for a blog-only or stats-only run. |
includeRatingOnlyReviews | boolean | optional | 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 | boolean | optional | Collect Naver Blog and cafe posts linked to the place, with exact publish dates. |
maxBlogReviews | integer | optional | Maximum linked blog/cafe posts per place. Naver exposes at most 100 per place. |
includeReviewPhotos | boolean | optional | Include photo and video-thumbnail URLs attached to each visitor review. |
includeReviewStats | boolean | optional | Emit one stats record per place: average rating, rating distribution, themes, top menus, voted keywords, and review counts. |
visitedSince | string | optional | 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 | array | optional | Visitor review IDs and blog post URLs to skip. Useful for incremental runs that only want new reviews. |
maxConcurrency | integer | optional | How many places to scrape in parallel. Higher is faster but increases rate-limit risk. |
maxItems | integer | optional | Hard cap on total records emitted across all places. |
proxyConfiguration | object | optional | Optional. Leave empty to use direct requests; the actor escalates to an Apify datacenter proxy only after a real block. |
3. Start an Actor run
Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.
Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.
import json
import os
import urllib.request
# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
actor_input = json.load(stream)
token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
"https://api.apify.com/v2/acts/YRhCBuZlgIYwIEIUT/runs?timeout=120&maxTotalChargeUsd=0.50",
data=json.dumps(actor_input).encode("utf-8"),
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.
4. Inspect the actual results
Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.
Naver Place visitor reviews, linked blog posts with publish dates, and per-place rating statistics, distinguished by the reviewType field.
Questions before you run
Which inputs are required?
No top-level fields are marked required in the published schema. Conditional requirements can still apply; check the README.
What does this guide verify?
The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.
What if the run request times out?
Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.
Generated from source build pizAoyiv3kJIJ7ul8 and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.