# Cào dữ liệu VOZ｜Xuất bài viết, bình luận VOZ.vn ra JSON (`claude_code_reviewer/voz-scraper`) Actor

Cào VOZ (voz.vn), diễn đàn lớn nhất Việt Nam, không cần đăng nhập hay API: danh sách chủ đề của box (lọc từ khóa tiêu đề), bài đầu và toàn bộ bình luận đã bỏ trích dẫn, kèm tác giả, lượt xem, thời gian ISO. Xuất JSON/CSV/Excel. Dùng cho social listening, giám sát thương hiệu, nghiên cứu thị trường.

- **URL**: https://apify.com/claude_code_reviewer/voz-scraper.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 danh sách chủ đề

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

## Cào dữ liệu VOZ｜Diễn đàn công nghệ & đời sống lớn nhất Việt Nam (không cần API, không cần đăng nhập)

Cào VOZ (voz.vn): danh sách chủ đề mới nhất của từng box, nội dung bài đầu và toàn bộ bình luận của một chủ đề. Dùng HTML công khai, không cần trình duyệt, kết quả là dữ liệu có cấu trúc (JSON/CSV/Excel).

### Các trường dữ liệu

#### Danh sách chủ đề của box (ListingRow, `content` là null)

| Trường | Kiểu | Mô tả |
|--------|------|-------|
| post_id | string | ID chủ đề |
| site | string | Luôn là `voz` |
| board | string | null | ID box (forumId bạn nhập khi truy vấn) |
| is_hidden | boolean | Dòng này có bị ẩn hay không. Trên VOZ hiện luôn là `false`; trường được giữ để cùng một lược đồ với hardwarezone-scraper |
| title | string | null | Tiêu đề |
| author | string | null | Người tạo chủ đề |
| reply_count | number | null | Số trả lời (trang gốc hiển thị dạng "3K"; đã chuyển thành số nguyên) |
| view_count | number | null | Lượt xem (xử lý tương tự "300K" / "4M") |
| created_at | string | null | Thời gian đăng (ISO 8601, kèm múi giờ +0700) |
| last_reply_at | string | null | Thời gian trả lời gần nhất (ISO 8601, kèm +0700) |
| post_url | string | null | Liên kết chủ đề |
| content | string | null | Nội dung (null ở chế độ danh sách) |
| source_mode | string | Chế độ đã dùng |
| source_query | string | Điều kiện truy vấn (ID box) |
| scraped_at | string | Thời gian cào (ISO 8601) |

#### Bài đầu (ThreadRow, cùng trường, có thêm `content`)

| Trường | Kiểu | Mô tả |
|--------|------|-------|
| content | string | null | Toàn văn bài đầu (đã bỏ thẻ HTML, bỏ phần trích dẫn, khoảng trắng được rút gọn) |

`board` của bài đầu luôn là `null` (chế độ chủ đề không có ID box). `reply_count` / `view_count` / `last_reply_at` luôn là `null` (các trường này chỉ có ở trang danh sách box).

#### Bình luận (ReplyRow, chỉ ở chế độ Chủ đề đầy đủ)

| Trường | Kiểu | Mô tả |
|--------|------|-------|
| reply_id | string | ID bình luận (ID phần tử bài viết; nếu thiếu thì dùng `{ID chủ đề}-{tầng}`) |
| post_id | string | ID chủ đề chứa bình luận |
| site | string | Luôn là `voz` |
| floor | number | null | Số tầng (#, bắt đầu từ 1, đánh số liên tục qua các trang) |
| is_hidden | boolean | Bài bị ẩn (trên VOZ hiện luôn `false`). Dòng `true` chỉ là chỗ giữ vị trí và **không tính phí** |
| author | string | null | Tác giả |
| content | string | null | Nội dung bình luận (đã bỏ thẻ HTML, bỏ phần trích dẫn) |
| created_at | string | null | Thời gian bình luận (ISO 8601, kèm +0700) |
| scraped_at | string | Thời gian cào (ISO 8601) |

Tên trường giống hệt hardwarezone-scraper (Singapore), lihkg-scraper (Hồng Kông) và ptt-scraper (Đài Loan) nên có thể gộp dữ liệu diễn đàn nhiều nước vào một bảng.

### Các chế độ

| Chế độ | Đầu vào | Đầu ra | Tính phí |
|--------|---------|--------|----------|
| forum | forumIds (ID box), keywords (lọc tiêu đề, tùy chọn) | Danh sách chủ đề | $0.002/dòng |
| thread | threadIds / threadUrls | Bài đầu ($0.008/bài) + toàn bộ bình luận ($0.003/bình luận) | Theo số lượng |

### Các tham số đầu vào

| Tham số | Kiểu | Mặc định | Mô tả |
|---------|------|----------|-------|
| mode | enum | forum | Chế độ: forum / thread (bắt buộc) |
| forumIds | array | `["17"]` | ID box, ví dụ 17 (Chuyện trò linh tinh), 70 (Tư vấn cấu hình), 36 (Apple), 42 (AI). Xem thêm các box tại voz.vn |
| threadIds | array | — | ID chủ đề |
| threadUrls | array | — | URL chủ đề, tự động lấy ID chủ đề |
| bulkInput | textarea | — | Dán hàng loạt, mỗi dòng một mục, tự động gộp vào ô tương ứng theo chế độ |
| keywords | array | — | Chế độ box: lọc theo từ khóa trong tiêu đề (để trống = không lọc) |
| maxItems | integer | 50 | Chế độ box: số chủ đề tối đa mỗi box; chế độ chủ đề: số chủ đề tối đa. Tối đa 2000 |
| maxReplies | integer | — | Chế độ chủ đề: số bình luận tối đa mỗi chủ đề (mỗi bình luận đều tính phí). Để trống = không giới hạn |
| keepQuotes | boolean | false | Chế độ chủ đề: giữ phần trích dẫn ("X đã nói: ...") trong nội dung. Mặc định loại bỏ |
| dateFrom | string | — | Chế độ box: chỉ lấy chủ đề từ thời điểm này (`3d`, `12h`, `2w` hoặc `MM/DD/YY`). Khi đặt sẽ dừng lật trang sớm |
| proxyConfiguration | proxy | Apify datacenter proxy | Mặc định bật. Nếu bị Cloudflare chặn, đổi sang RESIDENTIAL + quốc gia VN |

### Ví dụ đầu vào

#### 1. Chủ đề mới nhất của một box

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

#### 2. Giám sát theo từ khóa trong tiêu đề, chạy theo lịch mỗi ngày

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

#### 3. Một chủ đề đầy đủ (bài đầu + bình luận)

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

#### 4. Giới hạn chi phí cho chủ đề dài (100 bình luận đầu)

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

#### 5. Giữ nguyên phần trích dẫn

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

### Ví dụ kết quả

```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"
}
```

### Lưu ý

- Chỉ lấy nội dung công khai, không cần tài khoản hay token.
- **Không dùng dữ liệu để huấn luyện mô hình AI.** VOZ khai báo `ai-train=no` trong robots.txt; dữ liệu từ actor này chỉ dùng cho nghiên cứu, giám sát thương hiệu và phân tích thị trường hợp pháp.
- Actor chỉ truy cập các đường dẫn robots.txt cho phép (danh sách box và trang chủ đề). Không dùng `/search/`, `/whats-new/`, trang hồ sơ thành viên hay tệp đính kèm, và giữ tốc độ tối đa 60 yêu cầu/phút.
- Không có tìm kiếm toàn diễn đàn: tham số `keywords` chỉ lọc theo tiêu đề trong các box bạn chỉ định.
- Phần trích dẫn ("X đã nói: ... Nhấp để mở rộng...") mặc định bị loại khỏi `content` để không lặp lại bài của người khác; đặt `keepQuotes: true` nếu muốn giữ.
- `reply_count` / `view_count` trên trang gốc ở dạng viết tắt "3K" / "4M", đã chuyển thành số nguyên.
- Thời gian là ISO 8601 kèm múi giờ +0700 (giờ Việt Nam), giữ nguyên như trang gốc.
- Tự dừng sau 5 trang liên tiếp không có dữ liệu mới để không đốt chi phí; nếu đặt `dateFrom`, actor dừng ngay khi cả trang (không tính chủ đề ghim) đều cũ hơn mốc đó.
- VOZ chạy sau Cloudflare. Hiện tại datacenter proxy vẫn hoạt động; nếu về sau gặp thử thách Cloudflare, đổi proxy sang RESIDENTIAL và chọn quốc gia VN.

### Câu hỏi thường gặp (FAQ)

**Hỏi: Có cần đăng nhập không?**

Đáp: Không. Actor chỉ lấy danh sách chủ đề và bài viết công khai, không dùng bất kỳ chức năng nào yêu cầu đăng nhập.

**Hỏi: Có lấy được nhiều box cùng lúc không?**

Đáp: Có. Điền nhiều ID vào forumIds hoặc dán mỗi dòng một ID vào bulkInput.

**Hỏi: Làm sao biết ID box và ID chủ đề?**

Đáp: Trong URL: `voz.vn/f/chuyen-tro-linh-tinhtm.17/` thì ID box là `17`; `voz.vn/t/...bo-bim-sua.1089186/` thì ID chủ đề là `1089186`. Dán nguyên URL vào threadUrls cũng được.

**Hỏi: Tìm kiếm toàn diễn đàn theo từ khóa có được không?**

Đáp: Không. Trang tìm kiếm của VOZ nằm trong danh sách bị robots.txt cấm nên actor không dùng. `keywords` chỉ lọc tiêu đề trong các box đã chọn. Để theo dõi từ khóa, hãy chạy theo lịch mỗi ngày với `dateFrom: "1d"` trên các box liên quan.

**Hỏi: Một chủ đề dài có tốn nhiều tiền không?**

Đáp: Có thể. Chế độ chủ đề mặc định lấy toàn bộ, mỗi bình luận tính một sự kiện `review-item` ($0.003). Chủ đề phổ biến có thể có hàng nghìn bình luận, hãy đặt `maxReplies` (ví dụ `100`) để giới hạn; bài đầu tính riêng một `product-detail`. `maxItems` giới hạn số chủ đề, không phải số bình luận.

**Hỏi: Vì sao `board` là null ở chế độ chủ đề?**

Đáp: Trang chủ đề không chứa ID box và đầu vào chỉ có ID chủ đề, nên actor trả về null thay vì đoán.

**Hỏi: Bị chặn thì làm gì?**

Đáp: Log sẽ có dòng `Rate limited on` hoặc `[incomplete-data]`. Thử giảm số lượng, hoặc đổi proxy sang RESIDENTIAL với quốc gia VN.

### 📚 Hướng dẫn và công cụ liên quan

Hướng dẫn thực hành và công cụ miễn phí dựa trên actor này, tại **[AI Social API](https://aisocialapi.com/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper)** (tiếng Anh):

- 📖 Chuyên đề: [Dữ liệu diễn đàn Đông Nam Á: lấy bài viết và bình luận từ Pantip và VOZ khi không có API chính thức](https://aisocialapi.com/learn/topics/southeast-asia-forums/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper)
- 📖 Hướng dẫn: [Xây dựng pipeline phân tích cảm xúc diễn đàn không cần code với Apify + n8n + GPT](https://aisocialapi.com/learn/apify-n8n-forum-sentiment-pipeline/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper)
- 📊 Dữ liệu: [Bảng so sánh khả năng thu thập và chi phí của các diễn đàn châu Á](https://aisocialapi.com/tools/forum-scrapability/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper) — đo từ các lần chạy thật: diễn đàn nào chỉ cần request thường, diễn đàn nào cần IP residential, và mỗi mục tốn bao nhiêu
- 🛠 Công cụ miễn phí: [Kiểm tra nhanh cảm xúc trên diễn đàn](https://aisocialapi.com/tools/forum-sentiment/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper) · [Máy tính chi phí Apify](https://aisocialapi.com/tools/apify-cost/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper)
- 🤝 Không muốn tự chạy? [Để chúng tôi chạy giúp mỗi ngày](https://aisocialapi.com/monitor/?utm_source=apify\&utm_medium=readme\&utm_campaign=voz-scraper) — lên lịch chạy hằng ngày và gửi dữ liệu vào Google Sheet hoặc Slack của bạn, từ US$299/tháng.

Được duy trì bởi người đang vận hành hơn 30 Apify actor đang hoạt động.

### Tuyên bố miễn trừ trách nhiệm

Công cụ này chỉ dùng cho nghiên cứu học thuật và phân tích thương mại hợp pháp. Người dùng phải tuân thủ điều khoản dịch vụ của VOZ và pháp luật liên quan, tôn trọng robots.txt, và không dùng dữ liệu để huấn luyện mô hình AI. Không dùng công cụ để xâm phạm quyền riêng tư, phát tán thông tin sai lệch hay bất kỳ hành vi vi phạm pháp luật nào. Tác giả không chịu trách nhiệm về việc lạm dụng. Nếu chủ sở hữu trang yêu cầu gỡ bỏ, việc sử dụng sẽ dừng lại.

***

Cào VOZ, scraper VOZ, voz.vn, diễn đàn Việt Nam, Vietnam forum scraper, VOZ forum data, social listening Việt Nam, giám sát thương hiệu, nghiên cứu thị trường Việt Nam, xuất JSON CSV Excel

# Actor input Schema

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

Bạn muốn lấy gì? Chọn một chế độ rồi điền các ô tương ứng bên dưới.

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

ID box của VOZ (số, nằm trong URL dạng voz.vn/f/{slug}.{id}/), ví dụ 17 (Chuyện trò linh tinh), 70 (Tư vấn cấu hình), 36 (Apple), 42 (AI). Xem danh sách box tại voz.vn. Dùng cho chế độ Box.

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

ID chủ đề của VOZ (số, nằm trong URL dạng voz.vn/t/{slug}.{id}/), ví dụ 1089186. Dùng cho chế độ Chủ đề đầy đủ.

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

URL đầy đủ của chủ đề, ví dụ https://voz.vn/t/vozer-father-ver-2026-hoi-nhung-ong-bo-bim-sua.1089186/. Actor tự động lấy ID chủ đề.

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

**Mỗi dòng một mục**, nhấn Enter để xuống dòng, không cần dấu ngoặc kép hay dấu phẩy. Tự động được hiểu là ID box / ID chủ đề / URL tùy theo chế độ và gộp vào các ô bên trên. Copy cả một cột từ Google Sheet hoặc Excel rồi dán vào là nhanh nhất.

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

(Tùy chọn) Chế độ Box: chỉ giữ các chủ đề có tiêu đề chứa ít nhất một từ khóa. Để trống nếu không lọc. Đây là bộ lọc tiêu đề trong box, không phải tìm kiếm toàn diễn đàn.

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

Chế độ Box: số chủ đề tối đa cho mỗi box. Chế độ Chủ đề đầy đủ: số chủ đề tối đa (mặc định lấy toàn bộ bình luận của mỗi chủ đề, đặt maxReplies để giới hạn theo tầng). Tối đa 2000.

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

Áp dụng cho chế độ Chủ đề đầy đủ. Số bình luận tối đa lấy cho mỗi chủ đề. Mỗi bình luận được tính phí theo sự kiện review-item; chủ đề dài có thể có hàng nghìn bình luận, đặt giá trị này để giới hạn chi phí mỗi chủ đề. Lấy N tầng bình luận đầu tiên (tính theo số tầng #, tầng đã bị xóa có thể làm số dòng thực tế ít hơn N). Để trống = không giới hạn (mặc định). Không liên quan đến "Số lượng tối đa" (giới hạn số chủ đề).

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

Áp dụng cho chế độ Chủ đề đầy đủ. Mặc định phần trích dẫn ("X đã nói: ... Nhấp để mở rộng...") bị loại khỏi nội dung để tránh lặp lại bài viết khác. Bật để giữ nguyên.

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

Áp dụng cho chế độ Box, dựa trên thời điểm đăng hoặc trả lời gần nhất (lấy mốc mới hơn). Định dạng: thời gian tương đối 3d (3 ngày), 12h (12 giờ), 2w (2 tuần), hoặc ngày tuyệt đối MM/DD/YY. Để trống = không lọc. Khi đặt, actor dừng lật trang sớm (chủ đề ghim không bị ảnh hưởng), tiết kiệm chi phí khi chạy theo lịch.

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

Mặc định dùng Apify datacenter proxy: không dùng proxy thì chia sẻ IP thoát với các run khác trên nền tảng nên dễ bị diễn đàn giới hạn tốc độ (429). Phản hồi HTML nhỏ, chi phí proxy gần như bằng không. Nếu gặp thử thách Cloudflare, chuyển sang RESIDENTIAL và chọn quốc gia VN. Chỉ tắt khi dùng proxy riêng hoặc chạy thử trên máy.

## 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").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").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 --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"
        }
    }
}
```

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/fdDGyAmX5gfL58Mw3/builds/0bAuvBPAYtVPFmKYy/openapi.json
