# VOZ Scraper – Vietnam's Biggest Forum Threads & Replies (`claude_code_reviewer/voz-scraper-en`) Actor

Scrape VOZ (voz.vn), Vietnam's biggest tech and lifestyle forum, with no API or login: board thread listings (title keyword filter), main posts and all replies with quotes removed, plus author, views and ISO timestamps. Export JSON/CSV/Excel for social listening and brand monitoring.

- **URL**: https://apify.com/claude_code_reviewer/voz-scraper-en.md
- **Developed by:** [Chad](https://apify.com/claude_code_reviewer) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 thread listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## VOZ Scraper – Vietnam's Biggest Tech & Lifestyle Forum (No API, No Login)

Scrape VOZ (voz.vn): the latest threads of each board, and the main post plus all replies of any thread. Public HTML only, no browser, output as structured data (JSON/CSV/Excel).

### Output Fields

#### Board Thread Listing (ListingRow, `content` is null)

| Field | Type | Description |
|-------|------|-------------|
| post_id | string | Thread ID |
| site | string | Always `voz` |
| board | string | null | Board ID (the forumId used in the query) |
| is_hidden | boolean | Whether this row is hidden. Always `false` on VOZ today; kept so the schema is identical to hardwarezone-scraper |
| title | string | null | Title |
| author | string | null | Thread starter |
| reply_count | number | null | Reply count (the raw page shows abbreviations like "3K" - converted to an integer) |
| view_count | number | null | View count (same handling for "300K" / "4M") |
| created_at | string | null | Post time (ISO 8601, with a +0700 offset) |
| last_reply_at | string | null | Last reply time (ISO 8601, with a +0700 offset) |
| post_url | string | null | Thread link |
| content | string | null | Content (null in listing mode) |
| source_mode | string | Mode used |
| source_query | string | Query (board ID) |
| scraped_at | string | Scrape time (ISO 8601) |

#### Main post (ThreadRow, same fields plus `content`)

| Field | Type | Description |
|-------|------|-------------|
| content | string | null | Full main post text (HTML stripped, quoted text removed, whitespace collapsed) |

A main post's `board` is always `null` (thread mode has no board ID input); `reply_count` / `view_count` / `last_reply_at` are always `null` (those only exist on board listing pages).

#### Reply (ReplyRow, full thread mode only)

| Field | Type | Description |
|-------|------|-------------|
| reply_id | string | Reply ID (the post element ID; falls back to `{threadId}-{floor}` when missing) |
| post_id | string | Parent thread ID |
| site | string | Always `voz` |
| floor | number | null | Floor number (#, 1-based, continuous across pages) |
| is_hidden | boolean | Hidden post (always `false` on VOZ today). A `true` row is only a placeholder and is **never billed** |
| author | string | null | Author |
| content | string | null | Reply text (HTML stripped, quoted text removed) |
| created_at | string | null | Reply time (ISO 8601, with a +0700 offset) |
| scraped_at | string | Scrape time (ISO 8601) |

Field names are identical to hardwarezone-scraper (Singapore), lihkg-scraper (Hong Kong) and ptt-scraper (Taiwan), so you can merge forum data across countries into one table.

### Modes

| Mode | Input | Output | Billing |
|------|-------|--------|---------|
| forum | forumIds (board IDs), keywords (title filter, optional) | Thread listing | $0.002 per row |
| thread | threadIds / threadUrls | Main post ($0.008 each) + all replies ($0.003 each) | By volume |

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| mode | enum | forum | Mode: forum / thread (required) |
| forumIds | array | `["17"]` | Board IDs, e.g. 17 (Chuyện trò linh tinh / off-topic chat), 70 (PC build advice), 36 (Apple), 42 (AI). Browse voz.vn for more boards |
| threadIds | array | — | Thread IDs |
| threadUrls | array | — | Thread URLs; the thread ID is extracted automatically |
| bulkInput | textarea | — | Bulk paste, one item per line, merged into the matching field for the current mode |
| keywords | array | — | Board mode: title keyword filter (empty = no filter) |
| maxItems | integer | 50 | Board mode: max threads per board; thread mode: max threads. Up to 2000 |
| maxReplies | integer | — | Thread mode: max replies per thread (every reply is billed). Empty = unlimited |
| keepQuotes | boolean | false | Thread mode: keep quoted text ("X đã nói: ...") in content. Removed by default |
| dateFrom | string | — | Board mode: only threads since this time (`3d`, `12h`, `2w` or `MM/DD/YY`). Stops paging early when set |
| proxyConfiguration | proxy | Apify datacenter proxy | On by default. If Cloudflare ever blocks it, switch to RESIDENTIAL with country VN |

### Input Examples

#### 1. Latest threads of a board

```json
{
  "mode": "forum",
  "forumIds": ["17"],
  "maxItems": 50
}
```

#### 2. Daily keyword monitoring (scheduled)

```json
{
  "mode": "forum",
  "forumIds": ["36", "70"],
  "keywords": ["iPhone", "RTX"],
  "dateFrom": "1d",
  "maxItems": 100
}
```

#### 3. One full thread (main post + replies)

```json
{
  "mode": "thread",
  "threadUrls": [
    "https://voz.vn/t/vozer-father-ver-2026-hoi-nhung-ong-bo-bim-sua.1089186/"
  ]
}
```

#### 4. Cap the cost of a long thread (first 100 replies)

```json
{
  "mode": "thread",
  "threadIds": ["1089186"],
  "maxReplies": 100
}
```

#### 5. Keep quoted text

```json
{
  "mode": "thread",
  "threadIds": ["1089186"],
  "maxReplies": 40,
  "keepQuotes": true
}
```

### Sample Output

```json
{
  "post_id": "1089186",
  "site": "voz",
  "board": "17",
  "is_hidden": false,
  "title": "[Vozer Father ver.2026] Hội những ông bố bỉm sữa",
  "author": "vtalinh",
  "reply_count": 3000,
  "view_count": 300000,
  "created_at": "2025-04-11T08:15:15+0700",
  "last_reply_at": "2026-10-10T16:30:06+0700",
  "post_url": "https://voz.vn/t/vozer-father-ver-2026-hoi-nhung-ong-bo-bim-sua.1089186/",
  "content": null,
  "source_mode": "forum",
  "source_query": "17",
  "scraped_at": "2026-10-10T10:00:00.000Z"
}
```

### Notes

- Public content only; no account or token needed.
- **Not for AI model training.** VOZ declares `ai-train=no` in its robots.txt; data from this actor is for research, brand monitoring and lawful market analysis only.
- The actor only touches paths allowed by robots.txt (board listings and thread pages). It does not use `/search/`, `/whats-new/`, member profiles or attachments, and stays at or below 60 requests per minute.
- There is no site-wide search: `keywords` only filters titles inside the boards you specify.
- Quoted text ("X đã nói: ... Nhấp để mở rộng...") is removed from `content` by default so replies do not repeat other people's posts; set `keepQuotes: true` to keep it.
- `reply_count` / `view_count` appear as abbreviations ("3K" / "4M") on the raw page and are converted to integers.
- Timestamps are ISO 8601 with a +0700 offset (Vietnam time), as served by the site.
- Stops automatically after 5 consecutive pages with no new data; with `dateFrom` it stops as soon as a whole page of non-sticky threads is older than the cut-off.
- VOZ sits behind Cloudflare. Datacenter proxy works today; if a Cloudflare challenge appears later, switch the proxy to RESIDENTIAL with country VN.

### FAQ

**Q: Do I need to log in?**

A: No. The actor only reads public thread lists and posts and uses nothing that requires an account.

**Q: Can I scrape several boards at once?**

A: Yes. Add several IDs to forumIds or paste one per line into bulkInput.

**Q: How do I find a board or thread ID?**

A: It is in the URL: `voz.vn/f/chuyen-tro-linh-tinhtm.17/` means board ID `17`; `voz.vn/t/...bo-bim-sua.1089186/` means thread ID `1089186`. You can also paste the whole URL into threadUrls.

**Q: Can I search the whole forum by keyword?**

A: No. VOZ's search pages are disallowed in robots.txt, so the actor does not use them. `keywords` only filters titles inside the chosen boards. For keyword monitoring, schedule a daily run with `dateFrom: "1d"` on the relevant boards.

**Q: Will a long thread cost a lot?**

A: It can. Thread mode fetches everything by default and bills every reply as a `review-item` event ($0.003). Popular threads can have thousands of replies, so set `maxReplies` (for example `100`) to cap the cost; the main post is billed separately as one `product-detail`. `maxItems` limits the number of threads, not replies.

**Q: Why is `board` null in thread mode?**

A: A thread page does not contain the board ID and the input only has a thread ID, so the actor returns null instead of guessing.

**Q: What if I get blocked?**

A: The log will show `Rate limited on` or `[incomplete-data]`. Try fewer items, or switch the proxy to RESIDENTIAL with country VN.

### 📚 Related tutorials & tools

Hands-on guides and free tools built on this actor, at **[AI Social API](https://aisocialapi.com/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper-en)**:

- 📖 Guide: [Pantip API and Southeast Asia Forum Data: Getting Thai and Vietnamese Forum Posts and Comments Without an Official API](https://aisocialapi.com/learn/topics/southeast-asia-forums/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper-en)
- 📖 Tutorial: [Build a no-code forum sentiment pipeline with Apify + n8n + GPT](https://aisocialapi.com/learn/apify-n8n-forum-sentiment-pipeline/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper-en)
- 📊 Data: [Asian forum scrapability × cost table](https://aisocialapi.com/tools/forum-scrapability/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper-en) — measured on live runs: which forums need only a plain request, which need a residential IP, and what one item costs
- 🛠 Free tools: [Forum sentiment quick-check](https://aisocialapi.com/tools/forum-sentiment/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper-en) · [Apify cost calculator](https://aisocialapi.com/tools/apify-cost/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper-en)
- 🤝 Rather not run it yourself? [I run it for you](https://aisocialapi.com/monitor/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper-en) — scheduled daily, delivered to your Google Sheet or Slack, from US$299/mo.

Maintained by an operator running 30+ live Apify actors.

### Disclaimer

This tool is for academic research and lawful commercial analysis only. Users must comply with VOZ's terms of service and applicable law, respect robots.txt, and must not use the data to train AI models. Do not use it to violate anyone's privacy, spread misinformation or for any other unlawful purpose. The author is not responsible for misuse. If the site owner asks for removal, use will stop.

***

VOZ scraper, voz.vn, Vietnam forum scraper, Vietnamese forum data, VOZ forum threads and replies, Vietnam social listening, brand monitoring Vietnam, Vietnam market research, export JSON CSV Excel

# Actor input Schema

## `mode` (type: `string`):

What do you want to scrape? Pick a mode, then fill in the matching fields below.

## `forumIds` (type: `array`):

VOZ board (forum) IDs - the number in URLs like voz.vn/f/{slug}.{id}/, e.g. 17 (Chuyện trò linh tinh / off-topic chat), 70 (PC build advice), 36 (Apple), 42 (AI). Browse voz.vn for more boards. Used by Board mode.

## `threadIds` (type: `array`):

VOZ thread IDs - the number in URLs like voz.vn/t/{slug}.{id}/, e.g. 1089186. Used by Full thread mode.

## `threadUrls` (type: `array`):

Full thread URLs, e.g. https://voz.vn/t/vozer-father-ver-2026-hoi-nhung-ong-bo-bim-sua.1089186/. The thread ID is extracted automatically.

## `bulkInput` (type: `string`):

**One item per line** - press Enter, no quotes or commas. Lines are treated as board IDs / thread IDs / URLs depending on the mode and merged into the fields above. Copying a column from Google Sheets or Excel is the fastest way.

## `keywords` (type: `array`):

(Optional) Board mode: keep only threads whose title contains any keyword. Leave empty for no filter. This filters titles inside the board - it is not a site-wide search.

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

Board mode: max threads per board. Full thread mode: max number of threads (all replies of each thread are fetched by default; set maxReplies to cap them by floor). Up to 2000.

## `maxReplies` (type: `integer`):

Full thread mode only. Maximum replies to fetch per thread. Every reply is billed (review-item), and popular threads can have thousands, so this caps the cost per thread. Takes the first N reply floors (by floor number; deleted floors may make the actual count slightly lower than N). Leave empty = unlimited (default). Unrelated to "Max items", which limits the number of threads.

## `keepQuotes` (type: `boolean`):

Full thread mode only. By default quoted blocks ("X đã nói: ... Nhấp để mở rộng...") are removed from post content so replies are not duplicated. Turn on to keep them.

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

Board mode only; judged by thread start time or last-reply time (whichever is newer). Format: relative 3d (3 days), 12h (12 hours), 2w (2 weeks), or absolute MM/DD/YY. Leave empty = no filter. When set, paging stops early (sticky threads are unaffected), which saves cost on scheduled monitoring runs.

## `proxyConfiguration` (type: `object`):

Uses Apify datacenter proxy by default: without a proxy the run shares egress IPs with other runs on the platform and the forum may rate-limit it (429). HTML responses are small, so proxy traffic cost is negligible. If Cloudflare ever challenges the datacenter IPs, switch to RESIDENTIAL with country VN. Turn off only with your own proxy or for local testing.

## Actor input object example

```json
{
  "mode": "forum",
  "forumIds": [
    "17"
  ],
  "maxItems": 50,
  "keepQuotes": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "mode": "forum",
    "forumIds": [
        "17"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("claude_code_reviewer/voz-scraper-en").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 = {
    "mode": "forum",
    "forumIds": ["17"],
}

# Run the Actor and wait for it to finish
run = client.actor("claude_code_reviewer/voz-scraper-en").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 '{
  "mode": "forum",
  "forumIds": [
    "17"
  ]
}' |
apify call claude_code_reviewer/voz-scraper-en --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,claude_code_reviewer/voz-scraper-en"
        }
    }
}
```

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/6FbdkMxVW0Qhx0Wyg/builds/OaxChpLbcPvtFXWxK/openapi.json
