# Weibo Keyword Posts Scraper (`automation-lab/weibo-keyword-post-search`) Actor

Collect first-page public Weibo keyword post snapshots with stable IDs, text, authors, timestamps and engagement. Compare source-ranked observations across scheduled runs; no pagination or exhaustive coverage.

- **URL**: https://apify.com/automation-lab/weibo-keyword-post-search.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Social media, Marketing, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.92 / 1,000 item extracteds

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

## Weibo Keyword Posts Scraper

Collect **weibo keyword posts** as one anonymous public first-page snapshot per supplied keyword. Export stable post IDs, exposed text, source timestamps, public authors, engagement counts and links for recurring China market research.

This is a sample of source-ranked conversations, **not exhaustive social listening**. A higher result limit does not unlock more source pages. Scheduled runs repeat the snapshot; they do not guarantee every new post or incremental collection.

### Who is it for?

Brand researchers, analysts and reporting teams who want to compare publicly observed conversations about product names or topics. Use the dataset as a research sample rather than a complete mention census or historical archive.

### Why use it?

Discover posts from keywords instead of needing author UIDs or individual post links. Preserve numeric IDs as strings, retain all observed query attribution, and compare engagement snapshots using the observation timestamp. No Weibo account, cookies, API key or paid data supplier is required.

### Getting started

1. Enter one or more keywords, such as `小米` and `华为`.
2. Set a global maximum number of unique posts to export.
3. Run the Actor and check the terminal status.
4. Open the default dataset and export JSON, CSV or Excel.
5. Schedule repeat runs if useful, then compare post IDs in your own pipeline.

```json
{"keywords":["小米"],"maxItems":20}
```

### Input parameters

| Input | Default | Behavior |
| --- | --- | --- |
| `keywords` | Required | 1–20 nonempty strings, each at most 100 characters. Surrounding whitespace is trimmed and identical case-sensitive queries deduplicated. |
| `maxItems` | 20 | Global cap of 1–1000 unique posts across the run. Zero and unlimited are not supported. |

Keywords are searched independently in input order, not combined as an ALL filter. Weibo's comprehensive/relevance search determines the results. This Actor does not enforce exact phrases, whole-word boundaries or literal text matches; a returned post may be relevant without containing the query verbatim.

Pagination, date ranges, account credentials, cookies, supplied post IDs, user timelines and unknown input fields are rejected, not silently ignored.

### Coverage and result limits

Only the first anonymous public search page is inspected for each keyword. The source cap varies: pages may contain approximately ten posts, fewer posts, non-post cards or no posts. Larger `maxItems` values never retrieve additional pages.

The global cap selects the first valid unique posts encountered in keyword/source order. Every supplied keyword snapshot is still inspected even when the export cap is full, so selected posts can gain attribution from later keywords. This adds per-query runtime even for small export caps. Billing limits may reduce the delivered count further.

No newest-first order, complete history, exhaustive coverage, full text for long posts, complete author profiles, media downloads or comments are promised. Source timestamps can be relative or absolute strings and are not normalized.

### Extracted data

| Field | Meaning |
| --- | --- |
| `keywords` | Array of supplied queries whose inspected snapshots contained the retained post. Not necessarily literal matches. |
| `postId` | Stable numeric source ID as a precision-safe string. |
| `url` | Public mobile Weibo post link. |
| `text` | Search-card text with HTML removed; it may be truncated. |
| `createdAt` | Source timestamp string, or null. |
| `authorId`, `authorName`, `authorProfileUrl` | Public author identity/link, nullable when absent. |
| `repostsCount`, `commentsCount`, `likesCount` | Source engagement counts, nullable when absent or nonnumeric. |
| `isLongText` | Source long-text marker; no expansion is performed. |
| `scrapedAt` | UTC observation time for the first retained occurrence in this run. |

### Output example

This anonymized example follows the locally verified search-card structure. Identifiers, names and content are illustrative.

```json
{
  "keywords": ["小米"],
  "postId": "12345678901234567",
  "url": "https://m.weibo.cn/status/AbC12DeFg",
  "text": "Example public conversation about a product.",
  "createdAt": "Wed Jan 15 12:00:00 +0800 2025",
  "authorId": "1234567890",
  "authorName": "Example Author",
  "authorProfileUrl": "https://m.weibo.cn/u/1234567890",
  "repostsCount": 12,
  "commentsCount": 5,
  "likesCount": 42,
  "isLongText": false,
  "scrapedAt": "2025-01-15T12:00:00.000Z"
}
```

### Deduplication and snapshot comparison

A post ID appears once per run, even if several queries return it. Its `keywords` array contains all observed query associations across inspected pages. Text and engagement come from its first retained occurrence, not the latest query. Query attribution says where the source returned the post, not why it matched.

Join repeated runs by the string `postId`; keep `scrapedAt` to distinguish observations and compare engagement. A post disappearing from the next snapshot does not prove deletion, loss of relevance or lack of new discussion. Ranking changes and variable source coverage affect each sample. The Actor keeps no cross-run seen-ID state.

### How much does it cost to collect Weibo keyword posts?

Pricing is pay per event: one `start` fee per valid run and one `item` event per delivered unique post. Duplicate observations and extra query attribution have no separate item charge. Valid empty searches incur only the start fee. Invalid inputs fail before the start event; access failures after validation can incur the start fee without posts.

The start fee is **$0.005** at every tier. Per-post prices:

| Apify spend tier | Per unique post |
| --- | ---: |
| FREE | $0.00368 |
| BRONZE | $0.0032 |
| SILVER | $0.002496 |
| GOLD | $0.00192 |
| PLATINUM | $0.00192 |
| DIAMOND | $0.00192 |

Spend tiers follow your qualifying aggregate monthly Apify Store spend, not this Actor's record volume. At BRONZE, 1/5/10/25/100 delivered posts cost approximately $0.0082/$0.021/$0.037/$0.085/$0.325, including the start fee. These are event-tariff estimates, not guaranteed dataset counts or invoices; a single keyword usually provides far fewer than 100 posts. Check the active Apify pricing panel for your applicable tier. There are no additional account-cookie, proxy or supplier fees.

### Integrations

- Schedule snapshots in Apify, then join IDs and observation times in a spreadsheet or warehouse.
- Use dataset exports for qualitative coding or downstream Chinese-language sentiment analysis; sentiment is not computed here.
- Connect Apify dataset/run webhooks to Make, Zapier or n8n to load **successful** snapshots into a reporting pipeline.
- Keep full exports outside language-model context and pass only a bounded research sample to your analysis tool.

### API usage

Use your own Apify token in an environment variable, never in shared examples or logs. Start a run once and retain its run ID. The synchronous endpoint can time out while the Actor continues; check that same run rather than submitting a duplicate.

```bash
curl -X POST \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"keywords":["小米"],"maxItems":20}' \
  'https://api.apify.com/v2/acts/automation-lab~weibo-keyword-post-search/runs'
```

JavaScript:

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/weibo-keyword-post-search')
  .call({ keywords: ['小米'], maxItems: 20 });
if (run.status !== 'SUCCEEDED') throw new Error(`Run ${run.id}: ${run.status}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 20 });
console.log(items);
```

Python:

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/weibo-keyword-post-search').call(
    run_input={'keywords': ['小米'], 'maxItems': 20})
if run['status'] != 'SUCCEEDED':
    raise RuntimeError(f"Run {run['id']}: {run['status']}")
print(client.dataset(run['defaultDatasetId']).list_items(limit=20).items)
```

Private Actors require authorized account access; these examples do not imply current public availability.

### MCP usage

Select this Actor explicitly:

```bash
claude mcp add --transport http apify \
  'https://mcp.apify.com?tools=automation-lab/weibo-keyword-post-search'
```

Claude Desktop, Cursor and VS Code: use this equivalent client configuration (authentication is configured separately in your client):

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/weibo-keyword-post-search"}}}
```

Example prompts: “Collect first-page public snapshots for 小米 and 华为, at most 20 unique posts. Summarize the observed sample, not every Weibo mention.”

Discover actual names and argument schemas with scoped `tools/list`; selection also adds run/data helper tools. For an authorized invocation, start once, retain the run and storage IDs, then follow the same run. `call-actor` accepts `waitSecs` from 0–45 (default 30), not necessarily until completion. Configure the client request timeout to exceed the selected server wait plus a transport margin, within the 120-second total deadline. After a client timeout, recover/check the known run with `get-actor-run`, never start again just to poll. If no run ID is known, report uncertainty rather than blindly restart. Poll the same run with bounded backoff (for example 2/4/8 seconds, capped at 10); at the deadline report pending and the run ID, not a new run.

After success, use the discovered `get-dataset-items` argument schema and the returned `defaultDatasetId`, for example:

```json
{"datasetId":"<returned defaultDatasetId>","offset":0,"limit":20,"fields":"postId,keywords,text,url,scrapedAt"}
```

Prefer untransformed JSON and advance by source offsets (0, 20, 40), not transformed row counts; use pagination metadata to detect exhaustion. Retrieve at most 100 source rows and 64 KiB of serialized UTF-8 content admitted to model context across all pages, whichever comes first. Enforce byte limits host-side; disclose omitted/oversized content. Track source offsets, report truncation and continuation offset, and keep full exports in storage. Clients that cannot intercept responses must not claim a hard byte guarantee. Failed runs are failures, not successful datasets merely because some rows exist. No universal token-saving claim is made.

### Failure behavior and troubleshooting

Recognizable valid-empty source results succeed with zero posts. Visitor challenges, login/auth responses, HTTP errors and unknown response structures fail. The Actor uses at most three attempts per keyword with fresh anonymous browser contexts after access failure; it has no proxy or residential fallback.

All keyword snapshots must succeed before item export begins. A failed keyword therefore cannot be hidden behind a successful earlier keyword. Dataset writes interrupted later by platform or billing limits can be partial: always check terminal run status and count. There is no guarantee that private input or anti-bot challenges can be overcome.

If results are fewer than requested, remember the first-page cap and cross-keyword duplicates. If access fails, inspect the error and wait for a material source change rather than supplying cookies or unsupported pagination inputs. For help, contact <automation.labs.support@gmail.com> with the run link and expected workflow.

### Legality and responsible use

Collect only publicly exposed information that you are authorized to process. Respect applicable privacy laws, Weibo terms, retention requirements and rights of authors. Public availability is not permission for unrestricted reuse. Avoid sensitive profiling or publishing personal information unnecessarily. This Actor is not affiliated with Weibo and offers no legal compliance guarantee.

### Data handling

This Actor does not use AI or send inputs/posts to an AI provider. It uses Apify for execution and default dataset storage, public Weibo for source access, and our private GlitchTip for sanitized failure diagnostics. Company-owned platform costs are covered by the event tariff, with no supplier fees or paid proxy fallback. Browser cookies exist only in the ephemeral run context and are closed during cleanup; no session cache persists across runs.

Public author IDs/names, post text and engagement are intentionally included in your dataset. Input queries and datasets remain in your Apify account under its configured retention and access controls, rather than an Actor-defined expiration. Delete run storage through Apify when no longer needed; exports and downstream copies require your own deletion controls. Do not put sensitive personal information in keywords. Runtime logs contain counts and bounded access-error categories, not post content or credentials.

### Diagnostic privacy

Failed operations send sanitized diagnostic input, exceptions and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL queries are removed. Reports are retained for 30 days.

### FAQ

**Does a limit of 1000 retrieve more pages?** No. It caps export from one page per query only.

**Can I filter by date or collect every new post?** No. Unsupported date/pagination/account inputs are rejected. Scheduled runs are repeated source-ranked snapshots.

**Why does a post not literally contain my keyword?** Weibo determines relevance; this is not an Actor-side exact-text matcher.

**Does this expand long posts or scrape comments?** No. It returns exposed card text and counts, not complete long text or comment records.

### Related Actors

- [Weibo Posts and Profiles Scraper](https://apify.com/automation-lab/weibo-posts-profiles-scraper): supplied-UID public timelines and profile metadata, a different discovery input.
- [Weibo Hot Search Rankings Scraper](https://apify.com/automation-lab/weibo-public-hot-search-rankings): ranked topics, not keyword-discovered post records.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/weibo-keyword-post-search/changelog.md

# Actor input Schema

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

One to twenty nonempty queries, up to 100 characters each. Trim surrounding whitespace and remove identical case-sensitive duplicates. Search each independently in input order; queries are not an ALL filter. Weibo source relevance/ranking applies, not exact phrase or whole-word matching, newest-first order or exhaustive coverage. Only public post cards are exported.

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

Global export cap after stable-post-ID deduplication. First encountered posts are selected in keyword/source order; every keyword snapshot is still inspected to retain all observed query attribution. A larger limit never unlocks additional source pages. Actual count can be lower because of variable first-page caps, non-post cards, duplicates or billing limits. Zero/unlimited are unsupported.

## Actor input object example

```json
{
  "keywords": [
    "小米"
  ],
  "maxItems": 20
}
```

# Actor output Schema

## `overview` (type: `string`):

Default dataset of selected first-page post snapshots; inspect terminal status before treating output as complete.

# 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 = {
    "keywords": [
        "小米"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/weibo-keyword-post-search").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 = { "keywords": ["小米"] }

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/weibo-keyword-post-search").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 '{
  "keywords": [
    "小米"
  ]
}' |
apify call automation-lab/weibo-keyword-post-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/weibo-keyword-post-search"
        }
    }
}
```

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/XIxNRTjPnb4WewDOm/builds/x3DccRF5SN6Scl9nn/openapi.json
