# LIHKG Scraper – Hong Kong Forum Threads, Replies & Sentiment (`claude_code_reviewer/lihkg-scraper-en`) Actor

Scrape LIHKG (a major Hong Kong forum) threads and replies for social listening: title, author, reply count, reactions, content and timestamps. No API or login. Export JSON/CSV/Excel. Ideal for HK sentiment analysis and brand monitoring.

- **URL**: https://apify.com/claude\_code\_reviewer/lihkg-scraper-en.md
- **Developed by:** [Chad](https://apify.com/claude_code_reviewer) (community)
- **Categories:** News, Social media, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 threads

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

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

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## LIHKG Scraper (No API, No Login)

Scrape LIHKG (Hong Kong's largest online forum) — latest thread listings per category, and full thread content with all replies — via the public `api_v2` JSON endpoint, output as structured data.

This actor is built for English-speaking researchers, analysts, and engineers who need Hong Kong forum sentiment / social listening data. Note: LIHKG itself is a Cantonese/Traditional-Chinese forum, so scraped `title` / `content` fields will be in Chinese — this tool structures and exports that data, it does not translate it.

### Output Fields

#### Thread listing / thread content (ThreadRow)

| Field | Type | Description |
|---------|------|------|
| thread_id | string | Thread ID |
| title | string \| null | Thread title |
| content | string \| null | Thread body (null in listing mode) |
| author | string \| null | Author nickname |
| category | string \| null | Category name |
| reply_count | number \| null | Number of replies |
| like_count | number \| null | Like count |
| dislike_count | number \| null | Dislike ("question mark face") count |
| created_at | string \| null | Post time (ISO 8601) |
| thread_url | string | Thread URL |
| source_mode | string | Scrape mode (thread-list / thread) |
| source_query | string | Query used (category ID or thread ID) |
| scraped_at | string | Scrape timestamp (ISO 8601) |

#### Replies (ReplyRow)

| Field | Type | Description |
|---------|------|------|
| reply_id | string \| null | Reply ID (post_id) |
| thread_id | string | Parent thread ID |
| floor | number \| null | Floor number (msg_num) |
| author | string \| null | Author nickname |
| content | string \| null | Reply content (HTML tags stripped) |
| like_count | number \| null | Like count |
| dislike_count | number \| null | Dislike count |
| created_at | string \| null | Reply time (ISO 8601) |
| scraped_at | string | Scrape timestamp (ISO 8601) |

### Modes

| Mode | Input | Output | Billing |
|-----|------|------|------|
| thread-list | catIds (category ID list) | Thread listing (ThreadRow) | $0.002/row |
| thread | threadIds / threadUrls | Thread content ($0.008/thread) + all replies ($0.003/reply) | by volume |

### Input Fields

| Field | Type | Default | Description |
|-----|------|------|------|
| mode | enum | thread-list | Mode: thread-list (listing) / thread (full thread) |
| catIds | array | — | Category IDs, e.g. 1 (Chat), 2 (Sports), 5 (Current Affairs) |
| threadIds | array | — | List of thread IDs |
| threadUrls | array | — | Thread URLs; the ID is extracted automatically |
| bulkInput | textarea | — | Bulk paste, one item per line, auto-merged into the matching field |
| maxItems | integer | 50 | Max items to scrape (listing: per category; thread: total threads) |
| keywords | array | — | Title keyword filter (listing mode only; leave empty for no filtering) |
| proxyConfiguration | proxy | no proxy | Enable Apify Proxy for heavy scraping |

### Input Examples

#### Thread listing

```json
{
  "mode": "thread-list",
  "catIds": ["1", "5"],
  "maxItems": 100
}
````

#### Full thread and replies

```json
{
  "mode": "thread",
  "threadIds": ["4126423"],
  "maxItems": 50
}
```

#### Bulk thread URLs

```json
{
  "mode": "thread",
  "threadUrls": [
    "https://lihkg.com/thread/4126423/page/1",
    "https://lihkg.com/thread/4000000/page/1"
  ],
  "maxItems": 50
}
```

### Notes

- Only public content is scraped — no account or token required
- Uses the api\_v2 JSON endpoint (no browser — fast and low-cost)
- Reply content has HTML tags automatically stripped (`<br>`, `<img>`, `<span>`, etc.)
- Thread mode: `maxItems` limits the **number of threads**; all replies within each thread are scraped without limit
- Billed per event: one-time `actor-start` fee of $0.005, $0.002 per listing row, $0.008 per thread, $0.003 per reply
- Auto-stops after 5 consecutive pages with no new data — no idle burn
- LIHKG's api\_v2 may add an `X-LI-DEVICE` header check or a challenge in the future, and may block datacenter IPs. This is monitored via smoke tests on Apify Cloud (go/no-go); if blocked, the fallback is Apify residential proxy (`proxyConfiguration`) — not over-engineered in advance

### FAQ

**Q: Do I need to log in to view this data?**

A: No. This actor only scrapes public thread listings and replies — nothing that requires login.

**Q: Can I scrape multiple categories at once?**

A: Yes. Add multiple IDs to `catIds`, or paste them one per line via `bulkInput`.

**Q: How is reply HTML handled?**

A: Automatically. The `content` field is plain text — HTML tags are stripped and HTML entities are decoded (`&amp;` → `&`, `&lt;` → `<`, etc.).

**Q: Why is `content` null in thread-list mode?**

A: The listing API doesn't return thread body content, only titles and metadata. Use thread mode if you need the full text.

### Disclaimer

This tool is for academic research and lawful business analysis only. Users must comply with LIHKG's Terms of Service and applicable laws. Do not use this tool to invade others' privacy, spread false information, or engage in any other unlawful activity. The author accepts no responsibility for any misuse.

***

*LIHKG scraper, Hong Kong forum, HK social sentiment, LIHKG API, Hong Kong online discussion, forum thread scraper, HK opinion data*

# Actor input Schema

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

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

## `catIds` (type: `array`):

LIHKG category IDs (numeric), e.g. 1 (Chat), 2 (Sports), 5 (Current Affairs). Used by listing mode.

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

LIHKG thread IDs (numeric), e.g. 1234567. Used by thread mode.

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

Full LIHKG thread URLs, e.g. https://lihkg.com/thread/1234567/page/1. The thread ID is extracted automatically.

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

**One item per line** (press Enter for a new line, no quotes or commas). Treated as category IDs in listing mode, or thread IDs/URLs in thread mode, and merged into the matching field above at runtime. Fastest way is to copy a whole column from Google Sheets / Excel.

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

Listing mode: max threads per category. Thread mode: max threads to scrape (replies per thread are not limited by this).

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

Only keep threads whose title contains at least one of these keywords (listing mode). Leave empty for no filtering.

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

LIHKG is friendly to regular requests; it works without a proxy by default. Enable only if you hit blocks during heavy scraping.

## Actor input object example

```json
{
  "mode": "thread-list",
  "catIds": [
    "1"
  ],
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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": "thread-list",
    "catIds": [
        "1"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("claude_code_reviewer/lihkg-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": "thread-list",
    "catIds": ["1"],
}

# Run the Actor and wait for it to finish
run = client.actor("claude_code_reviewer/lihkg-scraper-en").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": "thread-list",
  "catIds": [
    "1"
  ]
}' |
apify call claude_code_reviewer/lihkg-scraper-en --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=claude_code_reviewer/lihkg-scraper-en",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "LIHKG Scraper – Hong Kong Forum Threads, Replies & Sentiment",
        "description": "Scrape LIHKG (a major Hong Kong forum) threads and replies for social listening: title, author, reply count, reactions, content and timestamps. No API or login. Export JSON/CSV/Excel. Ideal for HK sentiment analysis and brand monitoring.",
        "version": "1.0",
        "x-build-id": "qrUvJHD6H1jT9Gp58"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/claude_code_reviewer~lihkg-scraper-en/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-claude_code_reviewer-lihkg-scraper-en",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/claude_code_reviewer~lihkg-scraper-en/runs": {
            "post": {
                "operationId": "runs-sync-claude_code_reviewer-lihkg-scraper-en",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/claude_code_reviewer~lihkg-scraper-en/run-sync": {
            "post": {
                "operationId": "run-sync-claude_code_reviewer-lihkg-scraper-en",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "mode": {
                        "title": "🎯 Mode",
                        "enum": [
                            "thread-list",
                            "thread"
                        ],
                        "type": "string",
                        "description": "What do you want to scrape? Pick a mode and fill in the matching fields below.",
                        "default": "thread-list"
                    },
                    "catIds": {
                        "title": "📋 Category IDs",
                        "maxItems": 50,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "LIHKG category IDs (numeric), e.g. 1 (Chat), 2 (Sports), 5 (Current Affairs). Used by listing mode.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "threadIds": {
                        "title": "💬 Thread IDs",
                        "maxItems": 100,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "LIHKG thread IDs (numeric), e.g. 1234567. Used by thread mode.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "threadUrls": {
                        "title": "💬 Thread URLs",
                        "maxItems": 100,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Full LIHKG thread URLs, e.g. https://lihkg.com/thread/1234567/page/1. The thread ID is extracted automatically.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "bulkInput": {
                        "title": "📋 Bulk paste",
                        "type": "string",
                        "description": "**One item per line** (press Enter for a new line, no quotes or commas). Treated as category IDs in listing mode, or thread IDs/URLs in thread mode, and merged into the matching field above at runtime. Fastest way is to copy a whole column from Google Sheets / Excel."
                    },
                    "maxItems": {
                        "title": "📊 Max items",
                        "minimum": 1,
                        "maximum": 500,
                        "type": "integer",
                        "description": "Listing mode: max threads per category. Thread mode: max threads to scrape (replies per thread are not limited by this).",
                        "default": 50
                    },
                    "keywords": {
                        "title": "🔍 Keyword filter",
                        "maxItems": 50,
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Only keep threads whose title contains at least one of these keywords (listing mode). Leave empty for no filtering.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "proxyConfiguration": {
                        "title": "🌐 Proxy (advanced, usually off)",
                        "type": "object",
                        "description": "LIHKG is friendly to regular requests; it works without a proxy by default. Enable only if you hit blocks during heavy scraping.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
