# Naver Land Scraper - Property Listings, Prices & Locations (`abotapi/naver-land-listings`) Actor

Scrape structured property listings from Naver Land map URLs. Extract listing titles, prices, areas, addresses, GPS coordinates, property types, transaction types and source links for clean real estate datasets.

- **URL**: https://apify.com/abotapi/naver-land-listings.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 listing results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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 Land Listings

Naver Land Listings collects structured records from Naver Land. Search by keyword (the same search the site's own box performs: complex and region names such as 잠실 or 래미안) and/or paste any `new.land.naver.com` link: a map search URL (the map area, property types, and transaction filters you set on the site are all encoded in the URL), a single complex page such as `new.land.naver.com/complexes/111380`, a single listing page such as `new.land.naver.com/article/2651481309`, or a keyword results URL such as `new.land.naver.com/complexes?sk=잠실`. Keywords run first, every source is read independently, and results are merged and deduplicated, with identity, transaction, price, area, address, coordinates, and source links. Optional detail retrieval adds fields supplied by the source page.

### Why This Scraper?

- Keyword search built in, using the site's own search mechanism.
- Reads any Naver Land URL shape: map search views, complex pages, listing pages, and keyword result URLs.
- Returns stable identifiers for downstream deduplication.
- Includes source labels when the page provides them.
- Preserves the source object in raw for later fields.
- Supports multiple keywords and URLs in one run.
- Supports resumable runs and recurring change detection.

### Data You Get

| Field | Description | Example |
| --- | --- | --- |
| `id` | Source-derived id field | Sample id |
| `articleNo` | Source-derived articleNo field | Sample articleNo |
| `complexNo` | Source-derived complexNo field | Sample complexNo |
| `title` | Source-derived title field | Sample title |
| `propertyType` | Source-derived propertyType field | Sample propertyType |
| `tradeType` | Source-derived tradeType field | Sample tradeType |
| `price` | Source-derived price field | Sample price |
| `area` | Source-derived area field | Sample area |
| `floor` | Source-derived floor field | Sample floor |
| `direction` | Source-derived direction field | Sample direction |
| `address` | Source-derived address field | Sample address |
| `latitude` | Source-derived latitude field | Sample latitude |
| `longitude` | Source-derived longitude field | Sample longitude |
| `thumbnailUrl` | Source-derived thumbnailUrl field | Sample thumbnailUrl |
| `articleUrl` | Source-derived articleUrl field | Sample articleUrl |
| `sourceUrl` | Source-derived sourceUrl field | Sample sourceUrl |
| `crawledAt` | Source-derived crawledAt field | Sample crawledAt |
| `rank` | Source-derived rank field | Sample rank |
| `changeType` | Source-derived changeType field | Sample changeType |
| `changedFields` | Source-derived changedFields field | Sample changedFields |
| `firstSeenAt` | Source-derived firstSeenAt field | Sample firstSeenAt |
| `lastSeenAt` | Source-derived lastSeenAt field | Sample lastSeenAt |
| `raw` | Source-derived raw field | Sample raw |

### How to Use

Keyword search, URL reading, or both in one run. Keywords are resolved on the site exactly the way its search box resolves them, then read like any other source.

Search by keyword:

```json
{
  "searchKeywords": ["잠실", "래미안"],
  "maxItems": 20
}
```

A map search URL (set the map area, property types, and transaction filters on the site first, then copy the URL from the browser address bar):

```json
{
  "startUrls": ["https://new.land.naver.com/complexes?ms=2AM2Zq,3zhF96,16&a=APT:ABYG:JGC&e=RETAIL"],
  "maxItems": 20
}
```

A single complex page, with detail enrichment:

```json
{
  "startUrls": ["https://new.land.naver.com/complexes/111380"],
  "fetchDetails": true,
  "maxItems": 10
}
```

Recurring monitoring with change detection:

```json
{
  "searchKeywords": ["잠실"],
  "incrementalMode": true,
  "stateKey": "jamsil-watch",
  "emitExpired": true
}
```

Resume an interrupted collection by supplying resumeFromRunId. Resume and Incremental mode are separate controls.

### Send results into your apps (MCP connectors)

Results can also be piped into the apps you already use through Model Context Protocol (MCP) connectors. This is optional and never changes the dataset output.

1. Authorize a connector once under Apify → Settings → API & Integrations (Notion, Linear, Airtable, or Apify).
2. Select it in the `mcpConnectors` input.
3. For Notion, set `notionParentPageUrl` to the page under which one page per listing is created.
4. Optionally cap the export with `maxNotifyListings` (default 50 items per connector per run).

Each connector receives a condensed, human-readable summary per listing: a title plus the key fields (property type, transaction type, price, area, location, and listing link) flattened to plain text. Nested objects collapse to their main value and arrays are trimmed. The complete record, including the full source payload, always stays in the Apify dataset.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `searchKeywords` | array | prefill | Keyword search on Naver Land (complex and region names); runs before the URLs |
| `startUrls` | array | prefill | Naver Land URLs to read: map search URLs, complex pages, listing pages, or keyword result URLs |
| `maxItems` | string or object | platform default | Naver Land run setting |
| `fetchDetails` | string or object | platform default | Naver Land run setting |
| `resumeFromRunId` | string or object | platform default | Naver Land run setting |
| `incrementalMode` | string or object | platform default | Naver Land run setting |
| `stateKey` | string or object | platform default | Naver Land run setting |
| `emitUnchanged` | string or object | platform default | Naver Land run setting |
| `emitExpired` | string or object | platform default | Naver Land run setting |
| `mcpConnectors` | array | empty | Optional MCP connectors to export results into |
| `notionParentPageUrl` | string | empty | Notion parent page for the Notion connector export |
| `maxNotifyListings` | integer | 50 | Cap on items written to each connector per run |
| `proxy` | string or object | platform default | Naver Land run setting |

### Output Example

> Sample shape: values are illustrative placeholders, not from a live listing.

```json
{
  "id": "00000001",
  "articleNo": "00000001",
  "complexNo": "00000001",
  "title": "Sample Listing Title",
  "propertyType": "Apartment",
  "tradeType": "For sale",
  "price": "Sample price",
  "area": "84.00 square metres",
  "address": "Sample district",
  "latitude": 37.0000,
  "longitude": 127.0000,
  "articleUrl": "https://example.com/listing/00000001",
  "sourceUrl": "https://example.com/map",
  "changeType": "NEW",
  "changedFields": [],
  "firstSeenAt": "2026-01-01T00:00:00+00:00",
  "lastSeenAt": "2026-01-01T00:00:00+00:00",
  "raw": {}
}
```

### Plan Requirement

An Apify account and a run connection that can reach the source are required. Keep the default input connection settings unless your account requires a different configuration.

# Actor input Schema

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

Keyword search on Naver Land, exactly as the site's own search box does it: complex and region names such as 잠실 or 래미안. Each keyword is resolved on the site and its matching complexes are returned. Keywords run before the URLs below, and all results are merged and deduplicated.

## `startUrls` (type: `array`):

Any new.land.naver.com link works. Paste a map search URL (set the visible map area, property types, and transaction filters on the site, then copy the URL), a single complex page such as new.land.naver.com/complexes/111380, a single listing page such as new.land.naver.com/article/2651481309, or a keyword results URL such as new.land.naver.com/complexes?sk=잠실. Each URL is read independently and results are merged.

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

Maximum number of unique records returned across all URLs.

## `fetchDetails` (type: `boolean`):

Fetch additional detail fields for article cards when available.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to skip records already collected.

## `incrementalMode` (type: `boolean`):

Track NEW, UPDATED, UNCHANGED, REAPPEARED, and EXPIRED records for this URL scope.

## `stateKey` (type: `string`):

Optional name for the recurring monitoring scope.

## `emitUnchanged` (type: `boolean`):

Include records whose source-derived fields did not change.

## `emitExpired` (type: `boolean`):

Include records absent from a complete incremental scan.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify → Settings → API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write/digest. Leave empty to skip: this never changes the dataset output. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

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

Connection settings for the run.

## Actor input object example

```json
{
  "searchKeywords": [
    "잠실"
  ],
  "startUrls": [
    "https://new.land.naver.com/complexes?ms=2AM2Zq,3zhF96,16&a=APT:ABYG:JGC&e=RETAIL",
    "https://new.land.naver.com/complexes/111380",
    "https://new.land.naver.com/article/2651481309"
  ],
  "maxItems": 20,
  "fetchDetails": false,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "KR"
  }
}
```

# Actor output Schema

## `overview` (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": [
        "잠실"
    ],
    "startUrls": [
        "https://new.land.naver.com/complexes?ms=2AM2Zq,3zhF96,16&a=APT:ABYG:JGC&e=RETAIL",
        "https://new.land.naver.com/complexes/111380",
        "https://new.land.naver.com/article/2651481309"
    ],
    "maxItems": 20,
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "KR"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/naver-land-listings").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": ["잠실"],
    "startUrls": [
        "https://new.land.naver.com/complexes?ms=2AM2Zq,3zhF96,16&a=APT:ABYG:JGC&e=RETAIL",
        "https://new.land.naver.com/complexes/111380",
        "https://new.land.naver.com/article/2651481309",
    ],
    "maxItems": 20,
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "KR",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/naver-land-listings").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": [
    "잠실"
  ],
  "startUrls": [
    "https://new.land.naver.com/complexes?ms=2AM2Zq,3zhF96,16&a=APT:ABYG:JGC&e=RETAIL",
    "https://new.land.naver.com/complexes/111380",
    "https://new.land.naver.com/article/2651481309"
  ],
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "KR"
  }
}' |
apify call abotapi/naver-land-listings --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/naver-land-listings"
        }
    }
}
```

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/VWl5MjabpihpCSZB9/builds/KmEQfMgAQhVXm7QJL/openapi.json
