{
  "data": {
    "id": "pizAoyiv3kJIJ7ul8",
    "actId": "YRhCBuZlgIYwIEIUT",
    "userId": "zq8lKbpLzTjGDayPC",
    "startedAt": "2026-11-03T06:10:36.022Z",
    "finishedAt": "2026-11-03T06:10:40.147Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 4053,
      "runTimeSecs": 4.053,
      "computeUnits": 0.004503333333333333,
      "imageSizeBytes": 358093824
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "GK9YjZRyQZVzOdoH5",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Naver Place Reviews + Blog Scraper Input\",\n  \"description\": \"Collect Naver Place visitor reviews, linked Naver Blog posts, and aggregated rating statistics. Provide place URLs/IDs directly, or search by keyword to discover places first.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"placeUrls\": {\n      \"title\": \"Place URLs or IDs\",\n      \"type\": \"array\",\n      \"description\": \"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'.\",\n      \"editor\": \"stringList\",\n      \"prefill\": [\n        \"https://map.naver.com/p/entry/place/38239053\"\n      ]\n    },\n    \"searchKeywords\": {\n      \"title\": \"Search keywords\",\n      \"type\": \"array\",\n      \"description\": \"Keywords to discover places first, then scrape their reviews. Example: ['강남 맛집', '홍대 카페']. Can be combined with placeUrls.\",\n      \"editor\": \"stringList\"\n    },\n    \"maxPlacesPerKeyword\": {\n      \"title\": \"Max places per keyword\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum places to scrape per keyword search. Naver's search page returns up to 100 places per keyword.\",\n      \"minimum\": 1,\n      \"maximum\": 100,\n      \"default\": 3,\n      \"prefill\": 3\n    },\n    \"maxReviews\": {\n      \"title\": \"Max visitor reviews per place\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum visitor reviews to collect per place, across both the text-review stream and the rating-only stream. Naver paginates 50 reviews per request.\",\n      \"minimum\": 1,\n      \"maximum\": 5000,\n      \"default\": 100,\n      \"prefill\": 3\n    },\n    \"includeVisitorReviews\": {\n      \"title\": \"Include visitor reviews\",\n      \"type\": \"boolean\",\n      \"description\": \"Collect visitor reviews. Turn off for a blog-only or stats-only run.\",\n      \"default\": true,\n      \"prefill\": true\n    },\n    \"includeRatingOnlyReviews\": {\n      \"title\": \"Include rating-only reviews\",\n      \"type\": \"boolean\",\n      \"description\": \"Also collect reviews that have a star rating but no written text. These come from a separate Naver review stream and count toward maxReviews.\",\n      \"default\": true,\n      \"prefill\": false\n    },\n    \"includeBlogReviews\": {\n      \"title\": \"Include blog reviews\",\n      \"type\": \"boolean\",\n      \"description\": \"Collect Naver Blog and cafe posts linked to the place, with exact publish dates.\",\n      \"default\": true,\n      \"prefill\": false\n    },\n    \"maxBlogReviews\": {\n      \"title\": \"Max blog reviews per place\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum linked blog/cafe posts per place. Naver exposes at most 100 per place.\",\n      \"minimum\": 1,\n      \"maximum\": 100,\n      \"default\": 100,\n      \"prefill\": 10\n    },\n    \"includeReviewPhotos\": {\n      \"title\": \"Include review photos\",\n      \"type\": \"boolean\",\n      \"description\": \"Include photo and video-thumbnail URLs attached to each visitor review.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"includeReviewStats\": {\n      \"title\": \"Include review statistics\",\n      \"type\": \"boolean\",\n      \"description\": \"Emit one stats record per place: average rating, rating distribution, themes, top menus, voted keywords, and review counts.\",\n      \"default\": true,\n      \"prefill\": false\n    },\n    \"visitedSince\": {\n      \"title\": \"Visited since (YYYY-MM-DD)\",\n      \"type\": \"string\",\n      \"description\": \"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.\",\n      \"editor\": \"datepicker\"\n    },\n    \"excludeReviewIds\": {\n      \"title\": \"Exclude review IDs or blog URLs\",\n      \"type\": \"array\",\n      \"description\": \"Visitor review IDs and blog post URLs to skip. Useful for incremental runs that only want new reviews.\",\n      \"editor\": \"stringList\"\n    },\n    \"maxConcurrency\": {\n      \"title\": \"Max concurrent places\",\n      \"type\": \"integer\",\n      \"description\": \"How many places to scrape in parallel. Higher is faster but increases rate-limit risk.\",\n      \"minimum\": 1,\n      \"maximum\": 10,\n      \"default\": 3,\n      \"prefill\": 3\n    },\n    \"maxItems\": {\n      \"title\": \"Max items\",\n      \"type\": \"integer\",\n      \"description\": \"Hard cap on total records emitted across all places.\",\n      \"minimum\": 1,\n      \"maximum\": 5000,\n      \"default\": 100,\n      \"prefill\": 3\n    },\n    \"proxyConfiguration\": {\n      \"title\": \"Proxy configuration\",\n      \"type\": \"object\",\n      \"description\": \"Optional. Leave empty to use direct requests; the actor escalates to an Apify datacenter proxy only after a real block.\",\n      \"editor\": \"proxy\"\n    }\n  }\n}",
    "readme": "# Naver Place Visitor & Blog Review Finder\n\nNaver 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.\n\n## What this actor does\n\n- **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)\n- **Exact dates** — review creation date and timestamp, visit date, and blog publish date, including reviews older than one year\n- **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\n- **Aggregated statistics** — average rating, half-star distribution, review themes, top menus, voted-keyword counts, image/author counts, and text vs rating-only totals\n- **Two start modes** — give place URLs/IDs (including `naver.me` short links), search by keyword, or combine both\n- **Incremental runs** — filter by visit date and exclude known review IDs or blog URLs\n- **Clean records** — empty fields are omitted instead of returned as null\n\n## Output per record\n\nEvery record has a `reviewType` of `visitor`, `blog`, or `stats`.\n\n### Visitor review (`reviewType: \"visitor\"`)\n\n- `placeId`, `placeName`, `placeCategory`, `placeBusinessCategory`, `placeAddress`, `placeRoadAddress`, `placeRating`, `placeTotalReviews`, `placeBlogReviewCount`, `placeUrl` — place identity\n- `searchKeyword`, `searchRank` — keyword that found the place and its search rank\n- `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\n- `reviewDate`, `reviewCreatedAt`, `visitDate`, `visitCount`, `visitCountLabel` — when it was posted, when the visit happened, and how many visits the reviewer reports\n- `reviewerName`, `reviewerProfileUrl`, `reviewerImageUrl`, `reviewerFollowerCount`, `reviewerReviewCount`, `reviewerAverageRating` — reviewer identity and stats\n- `votedKeywords[]`, `visitTags[]` — Naver's official review-vote tags and visit-context tags\n- `reviewPhotos[]`, `mediaCount` — photo and video-thumbnail URLs (when `includeReviewPhotos` is enabled) and the total media count\n- `reviewReplyText`, `reviewReplyDate`, `hasReply`, `replyStatus` — the owner's reply\n- `menuItem`, `originType`, `language`, `translatedText`, `reviewReactionCount`, `reviewViewCount` — review context\n- `scrapedAt` — ISO 8601 timestamp\n\n### Blog review (`reviewType: \"blog\"`)\n\n- Place identity and `searchKeyword`/`searchRank`, same as above\n- `blogTitle`, `blogContents`, `blogContentsLength`, `blogUrl` — post title, excerpt, excerpt length, and link\n- `bloggerName`, `bloggerHome`, `bloggerProfileImageUrl` — blogger identity\n- `blogDate`, `blogSource`, `blogTypeName` — publish date, source type (`blog` or `cafe`), and localized label\n- `blogRank`, `isRepresentative`, `isSelfPaid` — position, representative flag, and self-paid flag\n- `blogThumbnailUrl`, `blogThumbnailUrls[]` — primary thumbnail and all thumbnails\n- `scrapedAt` — ISO 8601 timestamp\n\n### Stats (`reviewType: \"stats\"`, one per place)\n\n- Place identity and `searchKeyword`/`searchRank`\n- `averageRating`, `totalReviewCount`, `starDistribution`, `ratingDistribution` — average, total, integer histogram when available, and the exact half-star histogram\n- `reviewThemes[]`, `topMenus[]`, `votedKeywordStats[]` — theme labels, most-mentioned menu items, and voted-keyword counts\n- `imageReviewCount`, `authorCount`, `totalVisitorReviews`, `textReviewCount`, `ratingReviewCount`, `blogReviewCount` — review counts\n- `scrapedVisitorReviews`, `scrapedBlogReviews`, `runRatingDistribution`, `runKeywordDistribution` — what this run collected for the place\n- `scrapedAt` — ISO 8601 timestamp\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `placeUrls` | array | – | Naver Place URLs, `naver.me` links, or bare numeric place IDs |\n| `searchKeywords` | array | – | Keywords to discover places first; can be combined with `placeUrls` |\n| `maxPlacesPerKeyword` | integer | `3` | Places per keyword (1–100; Naver returns up to 100) |\n| `maxReviews` | integer | `100` | Visitor reviews per place across both streams (1–5,000) |\n| `includeVisitorReviews` | boolean | `true` | Collect visitor reviews |\n| `includeRatingOnlyReviews` | boolean | `true` | Also collect rating-only reviews from the separate stream |\n| `includeBlogReviews` | boolean | `true` | Collect linked blog and cafe posts |\n| `maxBlogReviews` | integer | `100` | Blog posts per place (1–100; Naver's hard cap) |\n| `includeReviewPhotos` | boolean | `false` | Include review photo and video-thumbnail URLs |\n| `includeReviewStats` | boolean | `true` | Emit one stats record per place |\n| `visitedSince` | date | – | Keep only reviews with a visit date on or after this date |\n| `excludeReviewIds` | array | – | Visitor review IDs and blog URLs to skip |\n| `maxConcurrency` | integer | `3` | Places scraped in parallel (1–10) |\n| `maxItems` | integer | `100` | Hard cap on total records across all places (1–5,000) |\n| `proxyConfiguration` | object | – | Optional proxy; direct requests are tried first and an Apify datacenter proxy is used only after a real block |\n\n### Example: reviews for specific places\n\n```json\n{\n  \"placeUrls\": [\n    \"https://map.naver.com/p/entry/place/38239053\",\n    \"1000750444\"\n  ],\n  \"maxReviews\": 500,\n  \"includeRatingOnlyReviews\": true,\n  \"includeReviewPhotos\": true,\n  \"includeReviewStats\": true,\n  \"maxItems\": 1000\n}\n```\n\n### Example: discover places by keyword first\n\n```json\n{\n  \"searchKeywords\": [\"강남 맛집\", \"홍대 카페\"],\n  \"maxPlacesPerKeyword\": 10,\n  \"maxReviews\": 100,\n  \"includeBlogReviews\": true,\n  \"maxBlogReviews\": 20,\n  \"includeReviewStats\": true,\n  \"maxItems\": 2000\n}\n```\n\n### Example: only new reviews since a date\n\n```json\n{\n  \"placeUrls\": [\"38239053\"],\n  \"visitedSince\": \"2026-09-01\",\n  \"excludeReviewIds\": [\"6abf13296171f06ddbf56400\"],\n  \"maxReviews\": 200\n}\n```\n\n## Use cases\n\n- **Market entry research** — read what local customers actually say about a category or area before entering the Korean market\n- **Restaurant and cafe competitive analysis** — compare ratings, rating distributions, voted keywords, and review volume across nearby competitors\n- **Customer sentiment tracking** — build a structured, NLP-ready archive of Korean-language reviews with exact dates and visit context\n- **Brand reputation monitoring** — track voted keywords, owner replies, and review themes for your own listed business\n- **Academic research** — study Korean consumer review behavior at scale, including rating-only reviews and blog coverage\n\n## FAQ\n\n**Is this affiliated with Naver?**\nNo. 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.\n\n**Do I need a Naver login, cookie, or API key?**\nNo. The actor uses public, cookieless endpoints. No login, cookie, or API key is required.\n\n**How many visitor reviews can I get per place?**\nUp 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.\n\n**What are rating-only reviews?**\nSome 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.\n\n**Why do some visitor reviews have no star rating?**\nNaver 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.\n\n**Why is `blogDate` now filled?**\nThe 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.\n\n**Why are some stats fields missing for a place?**\nNaver 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.\n\n**How exact are review dates?**\nReview 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.\n\n**Why might `reviewPhotos` be empty even with `includeReviewPhotos` enabled?**\nNot 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.\n\n**Do I need a proxy?**\nNo. 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.\n\n**How fresh is the data?**\nEach 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.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "naver-place-visitor-and-blog-review-finder",
      "title": "Naver Place Visitor & Blog Review Finder",
      "description": "Scrape Naver Place visitor reviews (text and rating-only), linked Naver Blog posts with exact dates, and rating statistics — average, distribution, themes, menus, and keywords — by place URL/ID or keyword search.",
      "version": "1.1",
      "buildTag": "latest",
      "defaultRunOptions": {
        "memoryMbytes": 1024
      },
      "meta": {
        "templateId": "python-empty"
      },
      "input": {
        "title": "Naver Place Reviews + Blog Scraper Input",
        "description": "Collect Naver Place visitor reviews, linked Naver Blog posts, and aggregated rating statistics. Provide place URLs/IDs directly, or search by keyword to discover places first.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "placeUrls": {
            "title": "Place URLs or IDs",
            "type": "array",
            "description": "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'.",
            "editor": "stringList",
            "prefill": [
              "https://map.naver.com/p/entry/place/38239053"
            ]
          },
          "searchKeywords": {
            "title": "Search keywords",
            "type": "array",
            "description": "Keywords to discover places first, then scrape their reviews. Example: ['강남 맛집', '홍대 카페']. Can be combined with placeUrls.",
            "editor": "stringList"
          },
          "maxPlacesPerKeyword": {
            "title": "Max places per keyword",
            "type": "integer",
            "description": "Maximum places to scrape per keyword search. Naver's search page returns up to 100 places per keyword.",
            "minimum": 1,
            "maximum": 100,
            "default": 3,
            "prefill": 3
          },
          "maxReviews": {
            "title": "Max visitor reviews per place",
            "type": "integer",
            "description": "Maximum visitor reviews to collect per place, across both the text-review stream and the rating-only stream. Naver paginates 50 reviews per request.",
            "minimum": 1,
            "maximum": 5000,
            "default": 100,
            "prefill": 3
          },
          "includeVisitorReviews": {
            "title": "Include visitor reviews",
            "type": "boolean",
            "description": "Collect visitor reviews. Turn off for a blog-only or stats-only run.",
            "default": true,
            "prefill": true
          },
          "includeRatingOnlyReviews": {
            "title": "Include rating-only reviews",
            "type": "boolean",
            "description": "Also collect reviews that have a star rating but no written text. These come from a separate Naver review stream and count toward maxReviews.",
            "default": true,
            "prefill": false
          },
          "includeBlogReviews": {
            "title": "Include blog reviews",
            "type": "boolean",
            "description": "Collect Naver Blog and cafe posts linked to the place, with exact publish dates.",
            "default": true,
            "prefill": false
          },
          "maxBlogReviews": {
            "title": "Max blog reviews per place",
            "type": "integer",
            "description": "Maximum linked blog/cafe posts per place. Naver exposes at most 100 per place.",
            "minimum": 1,
            "maximum": 100,
            "default": 100,
            "prefill": 10
          },
          "includeReviewPhotos": {
            "title": "Include review photos",
            "type": "boolean",
            "description": "Include photo and video-thumbnail URLs attached to each visitor review.",
            "default": false,
            "prefill": false
          },
          "includeReviewStats": {
            "title": "Include review statistics",
            "type": "boolean",
            "description": "Emit one stats record per place: average rating, rating distribution, themes, top menus, voted keywords, and review counts.",
            "default": true,
            "prefill": false
          },
          "visitedSince": {
            "title": "Visited since (YYYY-MM-DD)",
            "type": "string",
            "description": "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.",
            "editor": "datepicker"
          },
          "excludeReviewIds": {
            "title": "Exclude review IDs or blog URLs",
            "type": "array",
            "description": "Visitor review IDs and blog post URLs to skip. Useful for incremental runs that only want new reviews.",
            "editor": "stringList"
          },
          "maxConcurrency": {
            "title": "Max concurrent places",
            "type": "integer",
            "description": "How many places to scrape in parallel. Higher is faster but increases rate-limit risk.",
            "minimum": 1,
            "maximum": 10,
            "default": 3,
            "prefill": 3
          },
          "maxItems": {
            "title": "Max items",
            "type": "integer",
            "description": "Hard cap on total records emitted across all places.",
            "minimum": 1,
            "maximum": 5000,
            "default": 100,
            "prefill": 3
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Optional. Leave empty to use direct requests; the actor escalates to an Apify datacenter proxy only after a real block.",
            "editor": "proxy"
          }
        }
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "Naver Place Visitor & Blog Review Finder Output",
        "description": "Naver Place visitor reviews, linked blog posts with publish dates, and per-place rating statistics, distinguished by the reviewType field.",
        "properties": {
          "reviews": {
            "type": "string",
            "title": "Review Records",
            "description": "Dataset containing visitor reviews, blog reviews, and place review statistics.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "readme": "# Naver Place Visitor & Blog Review Finder\n\nNaver 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.\n\n## What this actor does\n\n- **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)\n- **Exact dates** — review creation date and timestamp, visit date, and blog publish date, including reviews older than one year\n- **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\n- **Aggregated statistics** — average rating, half-star distribution, review themes, top menus, voted-keyword counts, image/author counts, and text vs rating-only totals\n- **Two start modes** — give place URLs/IDs (including `naver.me` short links), search by keyword, or combine both\n- **Incremental runs** — filter by visit date and exclude known review IDs or blog URLs\n- **Clean records** — empty fields are omitted instead of returned as null\n\n## Output per record\n\nEvery record has a `reviewType` of `visitor`, `blog`, or `stats`.\n\n### Visitor review (`reviewType: \"visitor\"`)\n\n- `placeId`, `placeName`, `placeCategory`, `placeBusinessCategory`, `placeAddress`, `placeRoadAddress`, `placeRating`, `placeTotalReviews`, `placeBlogReviewCount`, `placeUrl` — place identity\n- `searchKeyword`, `searchRank` — keyword that found the place and its search rank\n- `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\n- `reviewDate`, `reviewCreatedAt`, `visitDate`, `visitCount`, `visitCountLabel` — when it was posted, when the visit happened, and how many visits the reviewer reports\n- `reviewerName`, `reviewerProfileUrl`, `reviewerImageUrl`, `reviewerFollowerCount`, `reviewerReviewCount`, `reviewerAverageRating` — reviewer identity and stats\n- `votedKeywords[]`, `visitTags[]` — Naver's official review-vote tags and visit-context tags\n- `reviewPhotos[]`, `mediaCount` — photo and video-thumbnail URLs (when `includeReviewPhotos` is enabled) and the total media count\n- `reviewReplyText`, `reviewReplyDate`, `hasReply`, `replyStatus` — the owner's reply\n- `menuItem`, `originType`, `language`, `translatedText`, `reviewReactionCount`, `reviewViewCount` — review context\n- `scrapedAt` — ISO 8601 timestamp\n\n### Blog review (`reviewType: \"blog\"`)\n\n- Place identity and `searchKeyword`/`searchRank`, same as above\n- `blogTitle`, `blogContents`, `blogContentsLength`, `blogUrl` — post title, excerpt, excerpt length, and link\n- `bloggerName`, `bloggerHome`, `bloggerProfileImageUrl` — blogger identity\n- `blogDate`, `blogSource`, `blogTypeName` — publish date, source type (`blog` or `cafe`), and localized label\n- `blogRank`, `isRepresentative`, `isSelfPaid` — position, representative flag, and self-paid flag\n- `blogThumbnailUrl`, `blogThumbnailUrls[]` — primary thumbnail and all thumbnails\n- `scrapedAt` — ISO 8601 timestamp\n\n### Stats (`reviewType: \"stats\"`, one per place)\n\n- Place identity and `searchKeyword`/`searchRank`\n- `averageRating`, `totalReviewCount`, `starDistribution`, `ratingDistribution` — average, total, integer histogram when available, and the exact half-star histogram\n- `reviewThemes[]`, `topMenus[]`, `votedKeywordStats[]` — theme labels, most-mentioned menu items, and voted-keyword counts\n- `imageReviewCount`, `authorCount`, `totalVisitorReviews`, `textReviewCount`, `ratingReviewCount`, `blogReviewCount` — review counts\n- `scrapedVisitorReviews`, `scrapedBlogReviews`, `runRatingDistribution`, `runKeywordDistribution` — what this run collected for the place\n- `scrapedAt` — ISO 8601 timestamp\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `placeUrls` | array | – | Naver Place URLs, `naver.me` links, or bare numeric place IDs |\n| `searchKeywords` | array | – | Keywords to discover places first; can be combined with `placeUrls` |\n| `maxPlacesPerKeyword` | integer | `3` | Places per keyword (1–100; Naver returns up to 100) |\n| `maxReviews` | integer | `100` | Visitor reviews per place across both streams (1–5,000) |\n| `includeVisitorReviews` | boolean | `true` | Collect visitor reviews |\n| `includeRatingOnlyReviews` | boolean | `true` | Also collect rating-only reviews from the separate stream |\n| `includeBlogReviews` | boolean | `true` | Collect linked blog and cafe posts |\n| `maxBlogReviews` | integer | `100` | Blog posts per place (1–100; Naver's hard cap) |\n| `includeReviewPhotos` | boolean | `false` | Include review photo and video-thumbnail URLs |\n| `includeReviewStats` | boolean | `true` | Emit one stats record per place |\n| `visitedSince` | date | – | Keep only reviews with a visit date on or after this date |\n| `excludeReviewIds` | array | – | Visitor review IDs and blog URLs to skip |\n| `maxConcurrency` | integer | `3` | Places scraped in parallel (1–10) |\n| `maxItems` | integer | `100` | Hard cap on total records across all places (1–5,000) |\n| `proxyConfiguration` | object | – | Optional proxy; direct requests are tried first and an Apify datacenter proxy is used only after a real block |\n\n### Example: reviews for specific places\n\n```json\n{\n  \"placeUrls\": [\n    \"https://map.naver.com/p/entry/place/38239053\",\n    \"1000750444\"\n  ],\n  \"maxReviews\": 500,\n  \"includeRatingOnlyReviews\": true,\n  \"includeReviewPhotos\": true,\n  \"includeReviewStats\": true,\n  \"maxItems\": 1000\n}\n```\n\n### Example: discover places by keyword first\n\n```json\n{\n  \"searchKeywords\": [\"강남 맛집\", \"홍대 카페\"],\n  \"maxPlacesPerKeyword\": 10,\n  \"maxReviews\": 100,\n  \"includeBlogReviews\": true,\n  \"maxBlogReviews\": 20,\n  \"includeReviewStats\": true,\n  \"maxItems\": 2000\n}\n```\n\n### Example: only new reviews since a date\n\n```json\n{\n  \"placeUrls\": [\"38239053\"],\n  \"visitedSince\": \"2026-09-01\",\n  \"excludeReviewIds\": [\"6abf13296171f06ddbf56400\"],\n  \"maxReviews\": 200\n}\n```\n\n## Use cases\n\n- **Market entry research** — read what local customers actually say about a category or area before entering the Korean market\n- **Restaurant and cafe competitive analysis** — compare ratings, rating distributions, voted keywords, and review volume across nearby competitors\n- **Customer sentiment tracking** — build a structured, NLP-ready archive of Korean-language reviews with exact dates and visit context\n- **Brand reputation monitoring** — track voted keywords, owner replies, and review themes for your own listed business\n- **Academic research** — study Korean consumer review behavior at scale, including rating-only reviews and blog coverage\n\n## FAQ\n\n**Is this affiliated with Naver?**\nNo. 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.\n\n**Do I need a Naver login, cookie, or API key?**\nNo. The actor uses public, cookieless endpoints. No login, cookie, or API key is required.\n\n**How many visitor reviews can I get per place?**\nUp 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.\n\n**What are rating-only reviews?**\nSome 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.\n\n**Why do some visitor reviews have no star rating?**\nNaver 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.\n\n**Why is `blogDate` now filled?**\nThe 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.\n\n**Why are some stats fields missing for a place?**\nNaver 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.\n\n**How exact are review dates?**\nReview 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.\n\n**Why might `reviewPhotos` be empty even with `includeReviewPhotos` enabled?**\nNot 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.\n\n**Do I need a proxy?**\nNo. 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.\n\n**How fresh is the data?**\nEach 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.\n",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "title": "Naver Place Reviews + Blog",
          "fields": {
            "type": "object",
            "properties": {
              "reviewType": {
                "type": "string",
                "description": "Record type: visitor, blog, or stats"
              },
              "placeId": {
                "type": "string",
                "description": "Naver Place ID"
              },
              "placeName": {
                "type": "string",
                "description": "Place name"
              },
              "placeCategory": {
                "type": "string",
                "description": "Place category (Korean)"
              },
              "placeBusinessCategory": {
                "type": "string",
                "description": "Naver business category, e.g. restaurant or cafe"
              },
              "placeAddress": {
                "type": "string",
                "description": "Place street address"
              },
              "placeRoadAddress": {
                "type": "string",
                "description": "Place road address"
              },
              "placeRating": {
                "type": "number",
                "description": "Place-level average visitor review score"
              },
              "placeTotalReviews": {
                "type": "integer",
                "description": "Total visitor review count on the place"
              },
              "placeBlogReviewCount": {
                "type": "integer",
                "description": "Total linked blog/cafe review count on the place"
              },
              "placeUrl": {
                "type": "string",
                "description": "Canonical place URL"
              },
              "searchKeyword": {
                "type": "string",
                "description": "Keyword that discovered this place (keyword-search mode only)"
              },
              "searchRank": {
                "type": "integer",
                "description": "1-based rank of the place in the keyword search result"
              },
              "reviewId": {
                "type": "string",
                "description": "Visitor review ID"
              },
              "reviewText": {
                "type": "string",
                "description": "Full review body (Korean), omitted for rating-only reviews"
              },
              "reviewHasText": {
                "type": "boolean",
                "description": "False when the review is rating-only"
              },
              "reviewRating": {
                "type": "number",
                "description": "Review star rating from 1 to 5, in 0.5 increments, when Naver exposes it; older anonymous reviews often omit it"
              },
              "reviewerName": {
                "type": "string",
                "description": "Reviewer nickname (masked by Naver)"
              },
              "reviewerProfileUrl": {
                "type": "string",
                "description": "Reviewer profile URL"
              },
              "reviewerImageUrl": {
                "type": "string",
                "description": "Reviewer profile image URL"
              },
              "reviewerFollowerCount": {
                "type": "integer",
                "description": "Reviewer follower count"
              },
              "reviewerReviewCount": {
                "type": "integer",
                "description": "Total reviews authored by the reviewer"
              },
              "reviewerAverageRating": {
                "type": "number",
                "description": "Reviewer's average rating across their reviews"
              },
              "reviewDate": {
                "type": "string",
                "description": "Review creation date (YYYY-MM-DD, KST)"
              },
              "reviewCreatedAt": {
                "type": "string",
                "description": "Review creation timestamp in ISO 8601 (KST)"
              },
              "visitDate": {
                "type": "string",
                "description": "Actual visit date (YYYY-MM-DD)"
              },
              "visitCount": {
                "type": "integer",
                "description": "Number of visits reported by the reviewer"
              },
              "visitCountLabel": {
                "type": "string",
                "description": "Korean visit label, e.g. 2번째 방문"
              },
              "votedKeywords": {
                "type": "array",
                "description": "Naver voted keyword tags, e.g. 음식이 맛있어요"
              },
              "visitTags": {
                "type": "array",
                "description": "Visit-context tags, e.g. 예약 없이 이용 or 혼자"
              },
              "mediaCount": {
                "type": "integer",
                "description": "Number of photos and videos attached to the review"
              },
              "reviewPhotos": {
                "type": "array",
                "description": "Photo and video-thumbnail URLs, when includeReviewPhotos is enabled"
              },
              "reviewReplyText": {
                "type": "string",
                "description": "Business owner's reply to the review"
              },
              "reviewReplyDate": {
                "type": "string",
                "description": "Owner reply date"
              },
              "hasReply": {
                "type": "boolean",
                "description": "True when the owner replied with text"
              },
              "replyStatus": {
                "type": "string",
                "description": "replied, no_reply, or unknown"
              },
              "reviewReactionCount": {
                "type": "integer",
                "description": "Number of reactions on the review"
              },
              "reviewViewCount": {
                "type": "integer",
                "description": "Number of views on the review"
              },
              "menuItem": {
                "type": "string",
                "description": "Menu item mentioned in the review"
              },
              "originType": {
                "type": "string",
                "description": "Review origin, e.g. 영수증 for receipt-verified reviews"
              },
              "language": {
                "type": "string",
                "description": "Review language code"
              },
              "translatedText": {
                "type": "string",
                "description": "Auto-translated review text, when Naver provides it"
              },
              "blogTitle": {
                "type": "string",
                "description": "Blog post title"
              },
              "blogContents": {
                "type": "string",
                "description": "Blog post excerpt"
              },
              "blogUrl": {
                "type": "string",
                "description": "Link to the full blog post"
              },
              "bloggerName": {
                "type": "string",
                "description": "Blogger name"
              },
              "bloggerHome": {
                "type": "string",
                "description": "Blogger's blog home URL"
              },
              "bloggerProfileImageUrl": {
                "type": "string",
                "description": "Blogger profile image URL"
              },
              "blogDate": {
                "type": "string",
                "description": "Blog post publish date (YYYY-MM-DD)"
              },
              "blogSource": {
                "type": "string",
                "description": "Source type: blog or cafe"
              },
              "blogTypeName": {
                "type": "string",
                "description": "Localized source label"
              },
              "blogThumbnailUrl": {
                "type": "string",
                "description": "Blog post thumbnail image URL"
              },
              "blogThumbnailUrls": {
                "type": "array",
                "description": "All blog post thumbnail image URLs"
              },
              "blogRank": {
                "type": "integer",
                "description": "Position in Naver's blog review list for this place"
              },
              "blogContentsLength": {
                "type": "integer",
                "description": "Length of the blog excerpt"
              },
              "isRepresentative": {
                "type": "boolean",
                "description": "Whether Naver marks this blog post as representative"
              },
              "isSelfPaid": {
                "type": "boolean",
                "description": "Whether the blog review is marked as self-paid"
              },
              "averageRating": {
                "type": "number",
                "description": "Average visitor rating from Naver stats"
              },
              "totalReviewCount": {
                "type": "integer",
                "description": "Total visitor review count from Naver stats"
              },
              "starDistribution": {
                "type": "object",
                "description": "Integer star distribution {5: n, 4: n, ...} when Naver supplies integer scores"
              },
              "ratingDistribution": {
                "type": "object",
                "description": "Half-star distribution keyed 0.5 to 5.0"
              },
              "reviewThemes": {
                "type": "array",
                "description": "Theme labels with review counts"
              },
              "topMenus": {
                "type": "array",
                "description": "Most-mentioned menu items with counts"
              },
              "votedKeywordStats": {
                "type": "array",
                "description": "Most-voted keyword tags with counts"
              },
              "imageReviewCount": {
                "type": "integer",
                "description": "Number of reviews with images"
              },
              "authorCount": {
                "type": "integer",
                "description": "Number of distinct review authors"
              },
              "totalVisitorReviews": {
                "type": "integer",
                "description": "Total visitor reviews reported by Naver stats"
              },
              "textReviewCount": {
                "type": "integer",
                "description": "Visitor reviews with written text"
              },
              "ratingReviewCount": {
                "type": "integer",
                "description": "Rating-only visitor reviews"
              },
              "blogReviewCount": {
                "type": "integer",
                "description": "Linked blog/cafe review total for the place"
              },
              "scrapedVisitorReviews": {
                "type": "integer",
                "description": "Visitor reviews emitted for this place in this run"
              },
              "scrapedBlogReviews": {
                "type": "integer",
                "description": "Blog reviews emitted for this place in this run"
              },
              "runRatingDistribution": {
                "type": "object",
                "description": "Rating distribution across visitor reviews emitted for this place"
              },
              "runKeywordDistribution": {
                "type": "array",
                "description": "Voted-keyword counts across visitor reviews emitted for this place"
              },
              "scrapedAt": {
                "type": "string",
                "description": "ISO 8601 scrape timestamp"
              }
            }
          },
          "views": {
            "overview": {
              "title": "Reviews Overview",
              "transformation": {
                "fields": [
                  "reviewType",
                  "placeName",
                  "searchKeyword",
                  "reviewRating",
                  "reviewText",
                  "blogTitle",
                  "blogDate"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "reviewType": {
                    "label": "Type",
                    "format": "text"
                  },
                  "placeName": {
                    "label": "Place",
                    "format": "text"
                  },
                  "searchKeyword": {
                    "label": "Keyword",
                    "format": "text"
                  },
                  "reviewRating": {
                    "label": "Rating",
                    "format": "number"
                  },
                  "reviewText": {
                    "label": "Review",
                    "format": "text"
                  },
                  "blogTitle": {
                    "label": "Blog Post",
                    "format": "text"
                  },
                  "blogDate": {
                    "label": "Blog Date",
                    "format": "text"
                  }
                }
              }
            }
          }
        }
      },
      "environmentVariables": {}
    },
    "buildNumber": "1.1.1",
    "imageDigest": "7207eb3b779f19140dedabba5bbb95b18e78a5310a8ec12473afc0e18c4046eb",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.1"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.004503333333333333
    }
  }
}