# 28Hse 香港屋網爬蟲｜樓盤放盤、業主自讓、樓盤詳情一鍵匯出（免 API） (`claude_code_reviewer/28hse-scraper`) Actor

免登入抓 28Hse 香港屋網：買賣與租務放盤列表、完整樓盤詳情，含售價、租金、實用面積、呎價、間隔、地區、屋苑與刊登日期，並標記業主自讓（自讓盤）／代理盤，輸出 JSON／CSV／Excel。獨有業主放盤叫價資料，香港房產估價與 proptech 市調必備。

- **URL**: https://apify.com/claude\_code\_reviewer/28hse-scraper.md
- **Developed by:** [Chad](https://apify.com/claude_code_reviewer) (community)
- **Categories:** Agents, Real estate, Integrations
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 搜尋樓盤

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 28Hse 香港屋網爬蟲｜樓盤放盤、業主自讓一鍵匯出（免 API）

抓 28Hse.com（香港屋網）：樓盤放盤列表、單一放盤全欄位詳情，走公開 HTML 端點（SSR + JSON-LD），不用登入、不用 token。輸出結構化資料，**業主自讓（FSBO）判定是本 Actor 的核心賣點**——代理行網站沒有的資料面，適合估價模型／proptech／代理研究部門補齊 asking-price 資料。

與同作者的 `centaline-scraper`（中原地產成交資料）互補：centaline 走成交，本 Actor 主打放盤詳情與業主盤過濾。

### 輸出欄位

#### 放盤列表（listing 模式）

| 欄位名稱 | 型別 | 說明 |
|---------|------|------|
| property\_id | string | 放盤 ID |
| title | string | null | 標題 |
| deal\_type | string | null | `buy`（買賣）或 `rent`（出租） |
| property\_type | string | null | 物業類型，例如 `apartment` |
| price | number | null | 價格（港元）。原始文字「售 $830 萬元」已換算成 8300000 |
| saleable\_area | number | null | 實用面積（呎） |
| gross\_area | number | null | 建築面積（呎）。**列表卡片本身不顯示建築面積，此欄位在 listing 模式恆為 null**，只有 detail 模式才有值 |
| unit\_price | number | null | 實用呎價（港元） |
| district | string | null | 地區，例如「荃灣」 |
| estate | string | null | 屋苑名稱 |
| rooms | number | null | 房數。開放式間隔（無獨立房間）誠實回 null，不猜測 |
| bathrooms | number | null | 浴室數 |
| is\_owner | boolean | **業主自讓（FSBO）判定**。頁面標示「業主盤」／「業主自讓」= `true`；「代理盤」或無標示 = `false` |
| agent\_name | string | null | 代理行名稱；業主自讓盤則為頁面顯示的業主聯絡名稱 |
| posted\_at | string | null | 刊登時間（ISO 8601）。原始為相對時間（「36 秒前」「N 天前」），已換算成絕對時間 |
| listing\_url | string | null | 放盤完整連結 |
| source\_mode | string | 固定 `listing` |
| scraped\_at | string | 抓取時間（ISO 8601） |

#### 放盤詳情（detail 模式，上面全部欄位 + 以下）

| 欄位名稱 | 型別 | 說明 |
|---------|------|------|
| address | string | null | 完整地址 |
| floor\_size\_sqft | number | null | 實用面積（呎），來源與 `saleable_area` 相同 |
| num\_rooms | number | null | 放盤頁 JSON-LD 原始房間數欄位。**注意**：這是網站自己 JSON-LD 提供的原始值，實測與頁面顯示的「N 房」（即上面的 `rooms` 欄位）不一定一致（見下方注意事項），兩個欄位都保留、各自誠實回報來源 |
| description | string | null | 放盤／屋苑描述全文 |
| agent\_address | string | null | 代理行（或業主聯絡）地址 |
| agent\_url | string | null | 代理行（或業主）頁面連結 |
| date\_published | string | null | 刊登時間（ISO 8601，含時區） |
| date\_modified | string | null | 最後更新時間（ISO 8601，含時區） |
| image\_count | number | null | 放盤圖片總數（含樓層/單位平面圖） |

### 模式說明

| 模式 | 輸入 | 輸出 | 計費 | 狀態 |
|-----|------|------|------|------|
| 📋 listing | dealType + propertyType（或 listingUrls） | 放盤列表 | `search-listing` $0.002/筆 | v1.0 |
| 🏠 detail | propertyIds 或 propertyUrls | 單一放盤全欄位 | `product-detail` $0.008/筆 | v1.0 |
| 📈 transactions | estateUrls（屋苑成交紀錄） | 成交紀錄 | `review-item` $0.003/筆 | **v1.1 尚未開放**，選這個模式會直接報錯 |

所有計費都在資料成功寫入 dataset **之後**才會收，Run 結束時 log 會印出 `total_items / charged / skipped` 讓你對帳。

### 輸入欄位

| 欄位 | 型別 | 預設 | 說明 |
|-----|------|------|------|
| mode | enum | listing | `listing` / `detail` / `transactions`（尚未開放，見上表）（必填） |
| dealType | enum | buy | `buy`（買賣）或 `rent`（出租）。listing 模式用；detail 模式用 propertyIds（而非 propertyUrls）時也要填 |
| propertyType | enum | apartment | 物業類型。只有「住宅」（apartment）經完整測試，其餘類型網址格式比照套用，未逐一驗證 |
| listingUrls | array | — | listing 模式選填，直接指定列表網址（覆蓋 dealType/propertyType），可填多個，各自獨立翻頁計數 |
| propertyIds | array | — | detail 模式用，放盤 ID（純數字），須搭配 dealType/propertyType 組網址 |
| propertyUrls | array | — | detail 模式用，放盤完整網址，自帶買賣/類型資訊最保險 |
| bulkInput | textarea | — | 批量貼上，一行一個，依目前模式自動併入對應欄位 |
| ownerOnly | boolean | false | 只適用 listing 模式：只保留業主自讓盤，過濾代理盤。**業主盤在單一分類中通常較稀少**，連續 5 頁沒有符合的放盤會提早停止（見下方注意事項） |
| maxItems | integer | 50 | listing 模式：每個列表來源最多抓幾筆；detail 模式：最多抓幾個放盤。上限 **500** |
| dateFrom | string | — | listing 模式適用，依放盤刊登時間篩選。格式 `3d`、`12h`、`2w`（相對時間）或 `MM/DD/YY`（絕對日期）。有設定時會提早停止翻頁，排程監控更省成本。detail 模式不適用 |
| proxyConfiguration | proxy | Apify datacenter proxy | 預設開啟；不用 proxy 會與其他 run 共用出口 IP 而被限流。自備 proxy 或本機測試才關 |

### 輸入範例

#### 1. 放盤列表：買盤住宅

```json
{
  "mode": "listing",
  "dealType": "buy",
  "propertyType": "apartment",
  "maxItems": 50
}
```

#### 2. 放盤詳情：單一放盤

```json
{
  "mode": "detail",
  "propertyUrls": ["https://www.28hse.com/buy/apartment/property-3948689"]
}
```

#### 3. 只要業主自讓盤（FSBO），限定出租

```json
{
  "mode": "listing",
  "dealType": "rent",
  "propertyType": "apartment",
  "ownerOnly": true,
  "maxItems": 100
}
```

#### 4. 批量抓多個放盤 ID

```json
{
  "mode": "detail",
  "dealType": "buy",
  "propertyType": "apartment",
  "bulkInput": "3948689\n3924956\n3990751"
}
```

#### 5. 排程監控：只抓 3 天內新刊登的放盤

```json
{
  "mode": "listing",
  "dealType": "buy",
  "propertyType": "apartment",
  "dateFrom": "3d",
  "maxItems": 200
}
```

### 注意事項

- 只抓公開內容，不需要帳號或 token，走公開 HTML 端點（SSR + JSON-LD），不開瀏覽器，速度快、成本低
- **價格解析**：原始文字「售 $830 萬元」的「萬」已自動換算成數字（× 10,000 = 8,300,000）；出租價格通常無「萬」單位，直接取數字
- **業主自讓（`is_owner`）判定**：只認頁面明確標示「業主盤」／「業主自讓」為 `true`；標題若只是提到「業主」兩個字（例如「相熟業主，價錢可議」）不會誤判——這種情況仍是代理行放的盤，`is_owner` 正確回 `false`
- **`ownerOnly` 的成本保護機制**：業主自讓盤在單一分類（例如「買樓·住宅」）通常比代理盤稀少很多。為了不讓爬蟲在完全沒有業主盤的分類裡無止盡翻頁燒錢，本 Actor 遵循「連續 5 個請求拿不到符合資料即停止」的鐵律——**啟用 `ownerOnly` 時，若連續 5 頁都沒有業主自讓盤，會直接停止**，即使該分類理論上還有更多（純代理）放盤沒抓完。若業主盤剛好分佈在較後面的頁數，可能因此漏抓；建議搭配較窄的篩選條件（`dealType`/`propertyType` 分開跑）增加業主盤密度
- **`rooms` 與 `num_rooms` 為什麼是兩個欄位**：`rooms`（listing 模式與 detail 模式共用的欄位）來自頁面顯示的「N 房」文字（可靠、與頁面畫面一致）；`num_rooms`（只有 detail 模式才有）是網站自己 JSON-LD 結構化資料裡的原始房間數欄位。實測同一個放盤這兩者可能不一致（例如某放盤頁面顯示「3 房」，但其 JSON-LD 的 `numberOfRooms` 卻是 `1`）——這是 28Hse 網站自己資料源的落差，不是本 Actor 的解析錯誤。兩個欄位都誠實保留各自來源的值，不互相覆蓋
- 開放式間隔（無獨立房間隔間）的放盤，`rooms` 會誠實回 `null`，不會猜測成 0 或 1
- `gross_area`（建築面積）**只有 detail 模式才有值**——放盤列表卡片本身只顯示實用面積，不顯示建築面積
- 連續 5 頁無新資料自動停止翻頁，不空轉燒費用；設了 `dateFrom` 的話，整頁放盤都比 `dateFrom` 舊就會直接停止翻頁（更省成本，僅 listing 模式適用）
- **屋苑成交紀錄（transactions 模式）尚未開放**，規劃於 v1.1。目前選這個模式會直接回傳錯誤訊息，不會消耗任何費用
- 28Hse 目前對本 Actor 使用的 datacenter proxy 無反爬蟲挑戰（無 CAPTCHA/JS challenge）；若未來網站加強防護，備援方案是切換 residential proxy，不預先過度設計

### 常見問題（FAQ）

**Q: 為什麼有些放盤的 `district`／`estate`／`price` 是 null？**

A: 極少數放盤卡片版型不完整（例如車位、非住宅類放盤，或該放盤本身缺資料），本 Actor 誠實回 `null`，不會用猜測值頂替。

**Q: `ownerOnly` 開啟後抓不到任何業主盤，正常嗎？**

A: 正常。業主自讓盤本來就比代理盤稀少，若連續 5 頁都沒有符合的放盤會提早停止（見上方注意事項），這是刻意的成本保護機制，不是 bug。可以試試換一個 `dealType`/`propertyType` 組合，或直接用 `listing_url` 去 28Hse 網站上手動確認該分類目前有沒有業主盤在架。

**Q: `propertyIds` 跟 `propertyUrls` 有什麼不同？**

A: `propertyUrls`（完整網址）自帶買賣類型與物業類型資訊，最保險；`propertyIds`（純數字 ID）需要額外填 `dealType`／`propertyType` 才能組出正確網址，兩者混用也可以。

**Q: 為什麼 listing 模式的 `gross_area`（建築面積）都是 null？**

A: 28Hse 的放盤列表卡片本身只顯示實用面積，不顯示建築面積；建築面積只在放盤詳情頁才有，所以只有 `detail` 模式的輸出才會有值。若需要建築面積，用 `detail` 模式抓對應放盤即可。

**Q: 什麼時候會有屋苑成交紀錄（土地註冊處資料）？**

A: 規劃在 v1.1。28Hse 的成交紀錄走 AJAX 端點，目前尚未確認完整的請求參數組合，會在確認後補上，屆時 `mode` 直接多一個可用選項，不需要改用其他 Actor。

### 免責聲明

本工具僅供學術研究及合法商業分析用途。使用者應遵守 28Hse 服務條款及相關法規。請勿以本工具進行任何侵害他人隱私、散布虛假資訊或其他違法行為。作者不對任何濫用行為承擔責任。

***

28Hse 爬蟲、香港樓盤、成交紀錄、業主自讓、香港房價、放盤資料

***

### 📚 延伸教學與工具

這隻 actor 背後的實戰教學與免費工具，都在 **[AI Social API](https://aisocialapi.com/zh-hant/?utm_source=apify\&utm_medium=readme\&utm_campaign=28hse-scraper)**：

- 📖 教學：[「有放盤」定「得出租」？地產代理話術一戳就穿——用四家代理的原始樓盤資料自己核實](https://aisocialapi.com/zh-hant/learn/hk-property-listing-verification/?utm_source=apify\&utm_medium=readme\&utm_campaign=28hse-scraper)
- 📊 原創資料：[站台涵蓋表：模式、欄位與定價](https://aisocialapi.com/zh-hant/coverage/?utm_source=apify\&utm_medium=readme\&utm_campaign=28hse-scraper) — 40 個站台各有哪些模式、實際回傳哪些欄位、每筆多少錢，全部從 actor 自己的 schema 生成
- 🛠 免費工具：[香港樓價查詢](https://aisocialapi.com/zh-hant/tools/hk-property/?utm_source=apify\&utm_medium=readme\&utm_campaign=28hse-scraper) · [Apify 成本試算](https://aisocialapi.com/zh-hant/tools/apify-cost/?utm_source=apify\&utm_medium=readme\&utm_campaign=28hse-scraper)
- 🤝 不想自己跑？[我幫你每天跑](https://aisocialapi.com/zh-hant/monitor/?utm_source=apify\&utm_medium=readme\&utm_campaign=28hse-scraper)——排程好每天送進你的 Google Sheet 或 Slack，每月 US$299 起。

由實際經營 40+ 隻上架 actor 的人維護。

# Actor input Schema

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

要抓什麼？選一個模式，填下面對應欄位就好。

## `dealType` (type: `string`):

放盤列表模式用（放盤詳情模式若用 propertyIds 而非 propertyUrls，也要填這個才能組出網址）。

## `propertyType` (type: `string`):

放盤列表模式用（放盤詳情模式若用 propertyIds 而非 propertyUrls，也要填這個才能組出網址）。只有「住宅」經完整測試（GREEN），其餘類型網址格式比照套用，未逐一驗證。

## `listingUrls` (type: `array`):

直接指定 28Hse 列表網址，例如 https://www.28hse.com/buy/apartment 或 https://www.28hse.com/rent/village。可填多個，各自獨立翻頁與計數。留空則用上面「買賣／出租」＋「物業類型」自動組網址。

## `propertyIds` (type: `array`):

28Hse 放盤 ID（網址 property-{id} 的數字部分），例如 3948689。放盤詳情模式用這個時，也要設定「買賣／出租」與「物業類型」才能組出正確網址。

## `propertyUrls` (type: `array`):

28Hse 放盤完整網址，例如 https://www.28hse.com/buy/apartment/property-3948689。放盤詳情模式用這個最保險（自帶買賣／類型資訊，不受上面欄位影響）。

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

**一行一個**，按 Enter 換行，不要加引號或逗號。依目前模式自動當成放盤 ID 或放盤網址，執行時自動併入上面對應欄位。從 Google Sheet / Excel 複製一整欄貼進來最快。

## `ownerOnly` (type: `boolean`):

只適用放盤列表模式：只保留頁面標示「業主盤」／「業主自讓」的放盤，過濾掉地產代理盤。業主自讓盤在單一分類中通常較稀少，若連續 5 頁都沒有符合的放盤會提早停止（見「注意事項」，避免空轉燒費用）。

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

放盤列表模式：每個列表來源最多抓幾筆。放盤詳情模式：最多抓幾個放盤 ID／網址。上限 500。

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

依放盤的「刊登時間」判斷（28Hse 列表預設由新到舊排序）。格式：相對時間 3d（3 天內）、12h（12 小時內）、2w（2 週內），或絕對日期 MM/DD/YY。留空表示不過濾。有設定時會提早停止翻頁，排程監控時省成本。放盤詳情模式不適用（單一放盤沒有「翻頁」可提早停止）。

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

預設走 Apify datacenter proxy：不用 proxy 時會跟平台上其他 run 共用出口 IP，容易被網站限流或擋下。頁面不算小（0.3–1.3MB），但 datacenter 流量費仍可忽略。自備 proxy 或本機測試才關掉。

## Actor input object example

```json
{
  "mode": "listing",
  "dealType": "buy",
  "propertyType": "apartment",
  "ownerOnly": false,
  "maxItems": 50,
  "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": "listing",
    "dealType": "buy",
    "propertyType": "apartment"
};

// Run the Actor and wait for it to finish
const run = await client.actor("claude_code_reviewer/28hse-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": "listing",
    "dealType": "buy",
    "propertyType": "apartment",
}

# Run the Actor and wait for it to finish
run = client.actor("claude_code_reviewer/28hse-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": "listing",
  "dealType": "buy",
  "propertyType": "apartment"
}' |
apify call claude_code_reviewer/28hse-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,claude_code_reviewer/28hse-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/KhMI0fjdMrHqXbGz2/builds/1oQyIxogxUJBSWwsC/openapi.json
