# Naver Stock Discussion Scraper (종목토론실) (`hgservices/naver-stock-discussion-scraper`) Actor

Scrape Naver stock discussion boards (네이버 종목토론실) for Korean and US stocks: every post with title, text, time, author, holder badge, views, likes and dislikes. Retail investor sentiment data from Korea, by stock code, ticker or name.

- **URL**: https://apify.com/hgservices/naver-stock-discussion-scraper.md
- **Developed by:** [Harish Garg](https://apify.com/hgservices) (community)
- **Features:** Limited permissions
- **Stats:** 5 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 scraped discussion posts

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 Stock Discussion Scraper (네이버 종목토론실)

**Scrape the Naver stock discussion boards (종목토론실, also called 종목토론방) for Korean and foreign stocks.** Get every post with its **title, full text, time, author, verified-holder badge, views, likes and dislikes**, newest first. Use it to measure **Korean retail investor sentiment** on KOSPI and KOSDAQ stocks, ETFs, and US stocks such as Tesla and NVIDIA.

The boards are on [Naver Pay Securities (네이버페이 증권)](https://m.stock.naver.com), the stock section of Naver Finance (네이버 증권). They are among the busiest stock forums in Korea, and popular stocks get new posts every few minutes.

- No Naver account and no login.
- No coding: run it in the browser, or call it from code or from an AI assistant.
- Export to JSON, CSV, Excel, or HTML, or read the rows through the API.

### What does the Naver Stock Discussion Scraper do?

You give it a list of stocks. For each stock, it opens the stock's discussion board and returns the posts, newest first. It stops at the post cap or at the oldest date that you set.

You can name a stock in four ways:

| Input form           | Examples                                                                                                            |
| -------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Korean stock code    | `005930` (Samsung Electronics), `000660` (SK hynix), `069500` (KODEX 200 ETF)                                       |
| Ticker               | `TSLA`, `NVDA`, `AAPL`, `QQQ`                                                                                       |
| Stock name           | `삼성전자`, `에코프로`, `테슬라`, `엔비디아`                                                                        |
| Naver stock page URL | `https://finance.naver.com/item/board.naver?code=005930`, `https://m.stock.naver.com/worldstock/stock/AAPL.O/total` |

It works for KOSPI and KOSDAQ stocks and ETFs, US stocks and ETFs on NASDAQ and NYSE, and other foreign stocks that have a Naver board, such as Hong Kong stocks.

### Use cases

- **Retail sentiment analysis** — feed post text into a sentiment model or an LLM, and track the mood of Korean individual investors (개미) for one stock or a whole watchlist.
- **Event studies** — collect all posts around earnings, a product launch, or a price shock, and compare the volume and tone before and after.
- **Holder vs. non-holder opinion** — Naver marks authors who own the stock (보유 인증). Filter on `isHolderVerified` to see what real shareholders say.
- **Korean investors on US stocks** — follow what Korean retail investors (서학개미) write about Tesla, NVIDIA, Apple, or QQQ.
- **Attention and hype signals** — count posts, views, and likes per day to find stocks with sudden retail interest.
- **Korean-language NLP datasets** — build a corpus of informal Korean financial text for classification or model training.
- **Daily monitoring** — start a run each day from your own code or workflow tool, with `dateFrom` set to the previous day, and collect only the new posts.

### Input

| Field        | Type     | Default | Description                                                                                                         |
| ------------ | -------- | ------- | ------------------------------------------------------------------------------------------------------------------- |
| `stocks`     | string\[] | —       | Stocks to scrape, one per line: Korean codes, tickers, stock names, or Naver stock page URLs. Required.             |
| `dateFrom`   | string   | —       | Return only posts written on or after this date, in Korea time. Format `YYYY-MM-DD`. Leave empty for no date limit. |
| `maxResults` | integer  | `100`   | The most posts to return for each stock, newest first. `0` means all posts, up to 100,000 per stock in one run.     |

Example input:

```json
{
    "stocks": ["005930", "에코프로", "TSLA"],
    "dateFrom": "2026-11-01",
    "maxResults": 500
}
```

### Output

You get one row for each post. This is a real post from the 삼성전자 (Samsung Electronics) board:

```json
{
    "type": "post",
    "stockCode": "005930",
    "stockName": "삼성전자",
    "market": "KOSPI",
    "postId": "431838499",
    "url": "https://m.stock.naver.com/domestic/stock/005930/discussion/431838499",
    "title": "이번에도 똑같다.",
    "text": "맨날 똑같은데 맨날 이번에는 다르데\n영익최고점 2021차트랑 데칼코마니...\n22년 영역이 줄었냐고 그때도 안줄었어.",
    "writtenAt": "2026-11-08T15:29:55+09:00",
    "author": "GOODTIME",
    "authorProfileId": "28660337077604813",
    "isHolderVerified": true,
    "views": 30,
    "likes": 1,
    "dislikes": 0,
    "imageCount": 0,
    "imageUrl": null,
    "postType": "normal",
    "isCleanbotPassed": true,
    "scrapedAt": "2026-11-08T06:38:58.411Z"
}
```

#### Output fields

| Field              | Description                                                                               |
| ------------------ | ----------------------------------------------------------------------------------------- |
| `type`             | `post` for a post row, `notice` for a row that explains a skipped or empty stock          |
| `stockCode`        | Korean stock code (`005930`) or Naver's code for a foreign stock (`TSLA.O`, `1810.HK`)    |
| `stockName`        | Stock name as Naver shows it, usually in Korean                                           |
| `market`           | Exchange: `KOSPI`, `KOSDAQ`, `NASDAQ`, `NYSE`, `HONG_KONG`, and others                    |
| `postId`, `url`    | Post ID and a link to the post on Naver                                                   |
| `title`, `text`    | Post title and full text, with line breaks kept                                           |
| `writtenAt`        | Time the post was written, in Korea time (`+09:00`)                                       |
| `author`           | Author's nickname                                                                         |
| `authorProfileId`  | Author's Naver profile ID                                                                 |
| `isHolderVerified` | `true` when Naver verified that the author owns the stock (보유 인증)                     |
| `views`            | View count                                                                                |
| `likes`            | Like count (공감)                                                                         |
| `dislikes`         | Dislike count (비공감)                                                                    |
| `imageCount`       | Number of images in the post                                                              |
| `imageUrl`         | Link to the post's main image, or `null`                                                  |
| `postType`         | `normal` for a regular user post, `itemNewsPrice` for Naver's automatic price-move alerts |
| `isCleanbotPassed` | Result of Naver's CleanBot content check for the post                                     |
| `scrapedAt`        | Time the row was collected (UTC)                                                          |

#### Notice rows

When a stock gives no posts, the dataset gets one `notice` row that tells you why:

```json
{
    "type": "notice",
    "code": "invalid_input",
    "message": "No stock found for \"ZZZZNOTASTOCK999\". Use a Korean stock code (005930), a ticker (AAPL), a name (삼성전자) or a Naver stock URL.",
    "input": "ZZZZNOTASTOCK999",
    "scrapedAt": "2026-11-08T06:39:07.765Z"
}
```

| `code`          | Meaning                                                             |
| --------------- | ------------------------------------------------------------------- |
| `invalid_input` | Naver does not know the stock, or the stock has no discussion board |
| `no_results`    | The board has no posts, or no posts since `dateFrom`                |
| `source_error`  | Naver did not answer for this stock after several attempts          |

To keep only posts, filter on `type = "post"`. The run's status message also gives the totals.

### How to use the Naver Stock Discussion Scraper

#### In Apify Console

1. Open the Actor and go to the **Input** tab.
2. In **Stocks**, add one stock per line, for example `005930` and `TSLA`.
3. Optional: set **Oldest post date**, for example `2026-11-01`.
4. Set **Max posts per stock**, for example `500`.
5. Click **Start**.
6. When the run finishes, open the **Output** tab. Download the posts as JSON, CSV, Excel, or HTML.

#### Through the API (HTTP)

This call runs the Actor, waits for it to finish, and returns the posts. Replace `<YOUR_APIFY_TOKEN>` with your token from **Apify Console → Settings → API & Integrations**.

```bash
curl -X POST "https://api.apify.com/v2/acts/hgservices~naver-stock-discussion-scraper/run-sync-get-dataset-items?format=json" \
  -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"stocks": ["005930", "TSLA"], "dateFrom": "2026-11-01", "maxResults": 200}'
```

A synchronous call waits for at most 5 minutes. For larger jobs, start the run with `POST /v2/acts/hgservices~naver-stock-discussion-scraper/runs`, then read the posts from `GET /v2/datasets/{defaultDatasetId}/items` when the run finishes.

#### With the JavaScript client

```bash
npm install apify-client
```

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const run = await client.actor('hgservices/naver-stock-discussion-scraper').call({
    stocks: ['005930', 'TSLA'],
    dateFrom: '2026-11-01',
    maxResults: 200,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const post of items.filter((row) => row.type === 'post')) {
    console.log(post.writtenAt, post.stockName, post.title, post.likes);
}
```

#### With the Python client

```bash
pip install apify-client
```

```python
import os

from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("hgservices/naver-stock-discussion-scraper").call(
    run_input={
        "stocks": ["005930", "TSLA"],
        "dateFrom": "2026-11-01",
        "maxResults": 200,
    }
)

for post in client.dataset(run.default_dataset_id).iterate_items():
    if post["type"] == "post":
        print(post["writtenAt"], post["stockName"], post["title"], post["likes"])
```

#### With AI assistants (Claude, ChatGPT) through the Apify MCP server

The [Apify MCP server](https://mcp.apify.com) lets an AI assistant run this Actor in a chat. Use this server URL, which adds the Naver Stock Discussion Scraper as a tool:

```text
https://mcp.apify.com?tools=hgservices/naver-stock-discussion-scraper
```

**Claude (claude.ai and Claude Desktop)**

1. Open **Settings → Connectors**.
2. Select **Add custom connector**.
3. Enter a name, for example `Apify`, and paste the server URL above.
4. Sign in to Apify when Claude asks.

**Claude Code**

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=hgservices/naver-stock-discussion-scraper"
```

**ChatGPT**

1. Turn on **Developer mode** in ChatGPT.
2. Open **Settings → Apps & Connectors**, then select **Create**.
3. Paste the server URL above in **MCP Server URL**, and select **OAuth** for authentication.
4. Sign in to Apify, then add the connector to a new chat with the **+** button.

For other MCP clients, such as Cursor or VS Code, get a ready-made configuration at [mcp.apify.com](https://mcp.apify.com).

Then ask in plain language, for example:

> Get the latest 300 posts from the 삼성전자 discussion board on Naver. Summarize whether retail investors are bullish or bearish, and list the three most-liked posts.

> Compare what Korean investors wrote about TSLA and NVDA since November 1. Which stock has more posts from verified holders?

### FAQ

**Do I need a Naver account?**
No. The Actor reads only public board pages that anyone can open without a login.

**How far back can I go?**
As far back as the board goes. Set `maxResults` to `0` and `dateFrom` to the oldest date that you need. One run returns at most 100,000 posts per stock. Busy stocks such as 삼성전자 can get thousands of posts a day, so use `dateFrom` to keep the run small.

**Does it get comments under each post?**
No. It returns the posts that the board list shows. It does not open each post to collect its comments.

**What if a stock name matches more than one stock?**
The Actor uses Naver's first search result for that name. For an exact match, use the stock code or ticker. For example, `토요타` currently matches the Toyota ADR (`TM`) on NYSE.

**What if I enter the same stock twice?**
When two inputs name the same stock, for example `086520` and `에코프로`, the Actor scrapes that stock once.

**Why is `text` empty for some posts?**
Naver posts automatic price-move alerts on the boards, for example "5% 이상 상승했어요". These posts have a title but no text. Their `postType` is `itemNewsPrice`, so you can filter them out.

**What time zone are the dates in?**
`writtenAt` and `dateFrom` use Korea time (KST, UTC+9). `scrapedAt` is in UTC.

**Can I run it every day?**
Yes. `dateFrom` is a fixed date, so set it to the previous day each time you start a run through the API or a client. With an Apify schedule, the input stays the same on each run, so use `maxResults` to cap each run instead. You can send the results to Google Sheets, Slack, a webhook, or a database with Apify integrations.

**Is it legal to scrape Naver stock discussions?**
The Actor collects only public posts that anyone can see without a login. Post content can include personal opinions and nicknames. Use the data in line with the laws of your country, data protection rules, and Naver's terms of service.

# Actor input Schema

## `stocks` (type: `array`):

One stock per line: a Korean stock code (005930), a foreign ticker (AAPL, TSLA), a stock name (삼성전자, 테슬라) or a Naver stock URL (finance.naver.com/item/board.naver?code=005930 or m.stock.naver.com/...).

## `dateFrom` (type: `string`):

Return only posts written on or after this date (Korea time), format YYYY-MM-DD. Leave empty to get posts until the cap.

## `maxResults` (type: `integer`):

The most posts to return for each stock, newest first. 0 = all (busy stocks have tens of thousands of posts a month). You pay per post.

## Actor input object example

```json
{
  "stocks": [
    "005930"
  ],
  "maxResults": 100
}
```

# Actor output Schema

## `dataset` (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 = {
    "stocks": [
        "005930"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("hgservices/naver-stock-discussion-scraper").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 = { "stocks": ["005930"] }

# Run the Actor and wait for it to finish
run = client.actor("hgservices/naver-stock-discussion-scraper").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 '{
  "stocks": [
    "005930"
  ]
}' |
apify call hgservices/naver-stock-discussion-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hgservices/naver-stock-discussion-scraper"
        }
    }
}
```

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/xXFbG2oX6UpaPtcTC/builds/h2uKereB2fQ51QUnT/openapi.json
