# Changelog of Naver Shopping Scraper (`searchapi/naver-shopping-scraper`) Actor

- **URL**: https://apify.com/searchapi/naver-shopping-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/searchapi/naver-shopping-scraper.md

## Changelog

### \[3.0.3] - 2026-08-29

#### Fixed

- The requested keyword is now entered and submitted through the public brand-store search form. Previous builds captured homepage recommendation APIs and could return unrelated products.
- Product cards are extracted only after the query-specific result heading and card grid load.
- Missing ratings and review counts are omitted instead of being fabricated as zero.
- Product links are stable Naver catalog URLs; expiring signed click-through URLs are never stored.
- `useApifyProxy: false` is now honored on Apify Cloud.
- Dataset writes are awaited and failures are no longer discarded.

#### Added

- Single-query and multi-query modes through `query` and `queries`.
- Relevance, newest, and most-reviewed sort modes.
- Bounded pagination, concurrency, retry, and timeout controls.
- Sessions, consistent browser settings, block-page detection, and optional authorized proxy support.
- A stable 27-field output contract with source, extraction method, result total, canonical identity, and ISO timestamp fields.
- Query scope is explicitly reported as `brand-store`; Naver autocomplete selects the store unless `startUrls` is supplied.

#### Security

- Updated Apify, Crawlee, and Playwright and resolved all production dependency audit findings.

### \[3.0.1] - 2026-06-13

#### Fixed

- **Dataset records had many null/empty fields** — fixed by:
  - **Skipping `display-catalogs` API** in the response drainer. The endpoint returns a flat array of product IDs (numbers), not product objects, which the previous code was normalizing as placeholder records with `title=null, price=null, …`. Now dropped entirely.
  - **Schema rewrite** to match the real Naver brand-store API: replaced Bing-style HTML-scraping fields (`availability`, `badges`, `condition`, `freeShipping`, `inStock`, `isSponsored`, `paymentOptions`, `warranty`, `seller`, `sellerRating`, `originalPrice`, `discount`, `discountPercent`, …) with Naver-specific fields (`brand`, `brandId`, `category`, `categoryId`, `categoryPath`, `categoryName`, `popularity`, `popularity2d`, `popularity7d`, `popularity30d`, `isOfficial`, `isLuxury`, `isServiceable`, `officialCount`, `officialCertifiedCount`, `certifiedCount`, `officialLowestPrice`, `officialCertifiedLowestPrice`, `certifiedLowestPrice`, `sellerId`, `catalogStatus`, `source`).
  - **Normalizer** now defaults missing numeric seller-trust fields to `0` (not `null`) when the API doesn't provide them, so `officialCount` / `officialCertifiedCount` / `certifiedCount` are always present.
  - **Handler** now passes a `nctx` object with `{url, searchUrl, query, market, page}` to the normalizer — this populates `searchUrl` (was always null), the `market` (e.g. `ko-KR`), and the `searchMetadata` object (`country` / `language` derived from market).

#### Improved

- `source` field on every record now indicates exactly which API produced it (`best-products:DAILY`, `best-products:WEEKLY`, `best-products:MONTHLY`, `simple-catalogs`, `graphql`) — 23/40 records currently come from `best-products:DAILY` alone.
- 4 popularities (raw, 2d, 7d, 30d) and 4-tier seller breakdown (official + certified) are now populated on every record.
- Added `views.overview` and `views.fullDetails` Apify view definitions in `dataset_schema.json` so the dataset renders in the Apify console.

### \[3.0.0] - 2026-06-13

#### Changed

- **Architecture rewrite** — the old DOM-scraping approach against `search.shopping.naver.com` was unusable: the endpoint is hard-blocked (HTTP 418) for scraper IPs. Replaced with an **auto-complete + preNavigationHooks API-capture** approach.
- `src/main.js` rewritten — calls `m.shopping.naver.com/api/modules/gnb/auto-complete` to resolve the query to either a brand store URL or a fashion-group category URL, then crawls that page with a Playwright `preNavigationHooks` response listener attached.
- `src/routes/handlers.js` rewritten — reads `window.__naverShoppingApiResponses` and parses product records from `n/v1/simple-catalogs`, `n/v2/channels/{uid}/display-catalogs`, `n/v2/channels/{uid}/best-products/catalogs`, and `veco-api.shopping.naver.com/window/api/v2/graphql` payloads.
- `src/canonical.js` — added `normalizeNaverShoppingProduct(raw, ctx)` normalizer (40 fields) and fixed a `engine: 'bing'` hardcode in `normalizeShoppingRecord`.
- `src/schema/input.js` — added `searchMode: 'auto' | 'brand' | 'category'`.
- `INPUT.json` — adds `searchMode`, `maxPages` (now in schema).
- `README.md` — rewritten to document the new auto-complete + API-capture approach and the 418 limitation.

#### Added

- `src/utils/autocomplete.js` — new helper that calls the auto-complete API and picks the best landing URL based on `searchMode`.
- Best-product source tracking: each record's `source` field tags which API the record came from (`simple-catalogs`, `display-catalogs`, `best-products:DAILY`, `best-products:WEEKLY`, `best-products:MONTHLY`, `graphql`).
- 4 popularity windows: `popularity`, `popularity2d`, `popularity7d`, `popularity30d`.
- 4-tier seller breakdown: `officialCount` / `officialLowestPrice` and `certifiedCount` / `certifiedLowestPrice` plus the `officialCertified*` variants.
- `isOfficial`, `isLuxury`, `isServiceable` boolean flags.
- Category breadcrumb as `categoryPath` array of IDs.

### \[2.0.0] - 2026-06-13

#### Added

- Initial release of Naver Shopping Scraper (v2.0.0).
- 39 canonical dataset fields, normalised through the shared `src/canonical.js → normalizeShoppingRecord` helper, matching the Bing / Google / Brave / Baidu `*.schema.json` family.
- Product grid scraping from `search.shopping.naver.com`.
- Price parsing in Korean Won (`₩` / `원`), with `price`, `priceNumeric`, `currency`.
- Discount detection (`originalPrice`, `discount`, `discountPercent`).
- Seller / merchant name and URL extraction.
- Rating and review count extraction.
- Shipping and stock flags.
- Korean query support.
- 2 dataset views: `overview` and `fullDetails`.
- Market default `ko-KR`, country `KR`, language `ko`.
