# Weibo API in Python: search, profiles and hot search (2026)

> Search Weibo posts by keyword, look up the accounts behind them by UID and read the hot search board from Python, without OAuth or a cookie. What the open API allows, code and cost.

Canonical page: https://okdata.online/guides/weibo-api-python/

Three endpoints: Weibo post search, Weibo account profile by UID and Weibo hot search, each a plain GET with an API key, no OAuth app and no login cookie. The worked example below is 9 calls and costs $0.018; a failed call is not charged.

Updated 2026-11-12

Weibo does have an open API, but it is built around the user who authorizes your app. The interface list on open.weibo.com runs through OAuth 2.0: read the authorized user's profile, their own posts, their home timeline, the comments on a post, and a few write calls such as sharing a link. Interfaces marked as advanced need a separate application. Keyword search is not in the standard list. The closest thing, `search/topics`, is an advanced interface that only searches posts inside a `#topic#` (the keyword has to be a topic between two # signs) and returns only the newest 200 results. Wider access goes through Weibo's commercial data interfaces, which come with their own subscription terms.

So most Python scripts for Weibo data scrape the site with a logged-in cookie, as [searching Weibo without a cookie](https://okdata.online/answers/weibo-search-without-cookie/) describes. This guide skips both the OAuth app and the cookie: each call is an HTTPS GET with an API key and `requests` is the only library. You end with a CSV of posts, a CSV of the accounts that posted them, and a check against the hot search board.

## Step by step

Set the key once: `export OKDATA_API_KEY=okd_...`. Every answer has `code` (`"ok"` on success); lists come in `data.items` with a `page`, single objects in `data.item`.

### Step 1: search posts by keyword

[Weibo post search](https://okdata.online/apis/weibo/posts/search/) takes `query`, typed as you would in Weibo's search box, and `sort`: `hot` (the default, most engagement) or `latest` (newest first). One call returns about 10 posts for $0.002. Each has `id`, `url`, `text`, `published_at`, `images`, `hashtags`, and `metrics.likes`, `metrics.comments` and `metrics.reposts`; video posts also carry a play count in `metrics.views`. The author comes with the UID in `author.id`, `author.name`, `author.followers` and `author.verified`.

```bash
curl -G "https://api.okdata.online/v1/weibo/posts/search" -H "Authorization: Bearer $OKDATA_API_KEY" \
  --data-urlencode 'query=预制菜' --data-urlencode 'sort=latest'
```

For page two and on, send `page.next_cursor` back as `cursor`, unchanged; stop when `page.has_more` is `false`. With `view=full`, `ext.region` gives the place Weibo shows as 发布于, `ext.source` the client it was posted from, and `ext.is_long_text` flags posts that search shows cut short.

### Step 2: look up the authors

[Weibo account profile](https://okdata.online/apis/weibo/users/get/) takes the numeric UID as `id`, the same number as `author.id` in search or the digits in `weibo.com/u/5730129846`. For $0.002 it returns `name`, `bio`, `followers`, `following`, `posts` and `verified`; with `view=full`, `ext` adds `verified_reason`, `ip_location`, `location` and `gender`. Looking up the UID behind a custom profile address is covered in [getting a profile from a Weibo UID](https://okdata.online/answers/weibo-user-profile-by-uid/).

```bash
curl -G "https://api.okdata.online/v1/weibo/users/get" -H "Authorization: Bearer $OKDATA_API_KEY" \
  --data-urlencode 'id=5730129846' --data-urlencode 'view=full'
```

### Step 3: read the hot search board

[Weibo hot search](https://okdata.online/apis/weibo/trends/list/) takes no parameters. One call returns the current board, about 50 rows, for $0.002: `rank`, `name` (the search term), `heat` and `url` (the search page for that topic). Paid placements are left out.

```bash
curl -G "https://api.okdata.online/v1/weibo/trends/list" -H "Authorization: Bearer $OKDATA_API_KEY"
```

### Step 4: the full script

The helper checks `body["code"]`, returns `None` for deleted or banned accounts, and retries rate limits and busy upstreams with the same `Idempotency-Key`, so a retry is never charged twice. `MAX_PAGES` caps the search.

```python
import csv
import os
import time
import uuid

import requests

API = "https://api.okdata.online"
KEY = os.environ["OKDATA_API_KEY"]
QUERY = "预制菜"
MAX_PAGES = 3     # search pages; each page is one call
TOP_AUTHORS = 5   # profile lookups


def call(path, **params):
    headers = {"Authorization": f"Bearer {KEY}", "Idempotency-Key": str(uuid.uuid4())}
    for attempt in range(4):
        body = requests.get(API + path, headers=headers, params=params, timeout=60).json()
        if body["code"] == "ok":
            return body
        if body["code"] == "not_found":
            return None  # deleted, banned or private: not charged
        if body.get("retry") in ("yes", "same_key"):
            time.sleep(body.get("retry_after_seconds") or 2 ** attempt)
            continue
        raise RuntimeError(f"{body['code']}: {body['message']} (request {body['request_id']})")
    raise RuntimeError(f"{path}: still failing after 4 tries")


def search(query, max_pages):
    cursor = None
    for _ in range(max_pages):
        body = call("/v1/weibo/posts/search", query=query, sort="latest", view="full",
                    **({"cursor": cursor} if cursor else {}))
        yield from body["data"]["items"]
        if not body["page"]["has_more"]:
            return
        cursor = body["page"]["next_cursor"]


posts = list(search(QUERY, MAX_PAGES))
with open("weibo_posts.csv", "w", newline="", encoding="utf-8-sig") as f:
    out = csv.writer(f)
    out.writerow(["post_id", "published_at", "uid", "author", "text", "likes", "comments", "reposts", "region", "url"])
    for p in posts:
        m = p["metrics"]
        out.writerow([p["id"], p["published_at"], p["author"]["id"], p["author"]["name"], p["text"],
                      m["likes"], m["comments"], m["reposts"], p["ext"].get("region"), p["url"]])

authors = {p["author"]["id"]: p["author"] for p in posts}
biggest = sorted(authors.values(), key=lambda a: a["followers"] or 0, reverse=True)[:TOP_AUTHORS]
with open("weibo_authors.csv", "w", newline="", encoding="utf-8-sig") as f:
    out = csv.writer(f)
    out.writerow(["uid", "name", "followers", "following", "posts", "verified", "verified_reason", "ip_location"])
    for a in biggest:
        body = call("/v1/weibo/users/get", id=a["id"], view="full")
        if body:
            u = body["data"]["item"]
            out.writerow([u["id"], u["name"], u["followers"], u["following"], u["posts"], u["verified"],
                          u["ext"].get("verified_reason"), u["ext"].get("ip_location")])

board = call("/v1/weibo/trends/list")["data"]["items"]
on_board = [t for t in board if QUERY in t["name"]]
print(f"{len(posts)} posts, {len(biggest)} profiles;", "on the board:" if on_board else "not on the board",
      ", ".join(f"#{t['rank']} {t['name']}" for t in on_board))
```

That run is the worked example: 3 search pages, 5 profiles and one board read, 9 calls. A daily version for a month (the same 9 calls each day) is $0.54.

## Good to know

- **What search shows.** Results are what Weibo's own search returns; posts Weibo hides from search do not appear, and search stops paging at the depth Weibo's search does.
- **Long posts.** Search can cut long posts short. Check `ext.is_long_text` (with `view=full`); the full text is on the post's page at `url`.
- **Nulls.** Shares and favorites are not shown on Weibo posts, so those `metrics` are null; total likes received is null on profiles. `meta.unavailable` names each null field.
- **Not in the catalog.** Comment threads and an account's own timeline are not covered; search, profiles and the board are.
- **UIDs.** Profiles take the numeric UID only, not a nickname or link.
- **Free cases.** Deleted or banned accounts answer `not_found`, which is free, like rate limits and every other error. The same request with the same `Idempotency-Key` within 24 hours returns the stored answer with `meta.replayed: true`.

To watch the board itself, open the [Weibo hot search tool](https://okdata.online/tools/hot-search/weibo/). For tracking what people say about a brand over time, see [word of mouth](https://okdata.online/solutions/word-of-mouth/).

## What the example costs

3 pages of the newest posts about 预制菜 (prepared meals), the profiles of the 5 authors with the most followers, and one read of the hot search board

| Endpoint | Calls | Price | Subtotal |
|---|---|---|---|
| [Weibo post search](https://okdata.online/apis/weibo/posts/search/) | 3 | $0.002 | $0.006 |
| [Weibo account profile](https://okdata.online/apis/weibo/users/get/) | 5 | $0.002 | $0.01 |
| [Weibo hot search](https://okdata.online/apis/weibo/trends/list/) | 1 | $0.002 | $0.002 |
| Total | 9 |  | $0.018 |

Prices in force when this page was built. A failed call costs nothing.

## In your AI (MCP)

Connect the MCP server once, then say what you want. The agent finds these endpoints, reads their prices and calls them on your balance.

Say: Search Weibo for the newest posts about 预制菜, three pages. Find the 5 authors with the most followers and give me their profiles, then tell me whether the topic is on the hot search board right now.

```json
{
  "endpoint": "weibo.posts.search",
  "params": {
    "query": "新品发布"
  },
  "idempotency_key": "<a new UUID>"
}
```

MCP: `https://api.okdata.online/mcp`

## Endpoints in this guide

- [Weibo post search](https://okdata.online/apis/weibo/posts/search/) `weibo.posts.search`: $0.002 per call · about 10 posts per page
- [Weibo account profile](https://okdata.online/apis/weibo/users/get/) `weibo.users.get`: $0.002 per call
- [Weibo hot search](https://okdata.online/apis/weibo/trends/list/) `weibo.trends.list`: $0.002 per call · about 50 board entries per page

## More about Weibo

- [Weibo API](https://okdata.online/apis/weibo/)
- [What should a social media monitoring job cost per month?](https://okdata.online/answers/social-listening-monthly-budget/)
- [How do I get IP location (IP属地) data from Weibo posts and Bilibili comments?](https://okdata.online/answers/weibo-bilibili-ip-location-data/)
- [How do I find Weibo bloggers (KOLs) in a niche?](https://okdata.online/answers/weibo-find-kols-in-niche/)
- [Is there an API for the Weibo hot search list?](https://okdata.online/answers/weibo-hot-search-api/)
- [How do I get alerted when my brand or a keyword hits Weibo hot search?](https://okdata.online/answers/weibo-hot-search-brand-alert/)
- [Does Weibo still have an open API for reading posts in 2026?](https://okdata.online/answers/weibo-official-api-2026/)
- [Trending topics API](https://okdata.online/roles/trends-list/)
- [Profile API](https://okdata.online/roles/accounts-get/)
- [Post search API](https://okdata.online/roles/posts-search/)
- [Weibo hot search: today’s list](https://okdata.online/tools/hot-search/weibo/)

## Sources

- [Weibo Open Platform: 微博API (interface list)](https://open.weibo.com/wiki/%E5%BE%AE%E5%8D%9AAPI) (read 2026-11-12)
- [Weibo Open Platform: 2/search/topics](https://open.weibo.com/wiki/2/search/topics) (read 2026-11-12)
