Weibo has an official API, but it is built for apps that users sign in to. You register an app, and almost every call runs with an OAuth 2.0 token that a Weibo user granted it. Keyword search and other users' posts sit in a separate paid API for enterprise developers. ToolzerHub returns public hot search, profiles, posts and comments from six routes.
What the official Weibo API requires
Weibo's open platform needs a developer account, an app with an App Key and App Secret, and a token from every user who authorises it. A normal token lasts 30 days. Until an app passes review it can authorise 15 test accounts, and one authorised user can make 100 requests a day within one app.
The free route list is built around that user: statuses/user_timeline returns the authorised user's own posts, and no keyword search is listed. The paid routes sit in the Business API.
| Job | Free list | Business API (paid) |
|---|---|---|
| Posts matching a keyword | none listed | search/statuses/limited |
| Another user's posts | statuses/user_timeline returns the authorised user's own |
statuses/user_timeline/other |
| Comments on a post | comments/show |
comments/show/all, the full list |
| A profile | users/show, after authorisation |
users/show_batch/other |
| Hot-search board | none listed | none listed |
The wiki says the data service accepts enterprise developers only. If you qualify, its subscription service pushes new posts for up to 20,000 keywords and 10,000 users per subscription, which suits real-time monitoring better than polling us.
Weibo data with ToolzerHub
We make ToolzerHub. Our Weibo API has six routes at https://api.toolzerhub.com/v1/weibo/, each 1 credit, sent with an x-api-key header. IDs are the digits from a profile or post URL.
| Route | Parameters | Returns |
|---|---|---|
trends/hot-search |
none | The current board |
search/topics |
keyword, page |
Topics: title, description, page_id |
search/users |
q |
Up to a few suggested profiles |
profiles/info |
uid |
Profile and counts |
posts/detail |
mid |
One post |
posts/comments |
mid |
First page of comments |
The hot-search board:
curl "https://api.toolzerhub.com/v1/weibo/trends/hot-search" \
-H "x-api-key: $TOOLZERHUB_API_KEY"
It returned 53 entries: 50 ranked, 1 pinned and 2 paid placements. Four are shown. kind tells them apart, and heat is null on some ranked rows.
{ "kind": "pinned", "rank": null, "word": "我们的长征路", "heat": null, "label": "热" }
{ "kind": "ranked", "rank": 1, "word": "AG 退役", "heat": 1302859, "label": "新" }
{ "kind": "ranked", "rank": 2, "word": "红果短剧自砍摇钱树", "heat": 1145046, "label": "热" }
{ "kind": "ad", "rank": null, "word": "阿福向全球医生发出心动的offer", "heat": null, "label": "官宣" }
User search needs Chinese-script queries: q=小米 returns 3 profiles.
curl -G "https://api.toolzerhub.com/v1/weibo/search/users" \
--data-urlencode "q=小米" -H "x-api-key: $TOOLZERHUB_API_KEY"
{ "count": 3, "entries": [
{ "id": "2202387347", "screen_name": "小米手机", "verified": true, "followers_count": 28472525 },
{ "id": "1786860821", "screen_name": "小米澎湃OS", "verified": true, "followers_count": 14047833 },
{ "id": "1771925961", "screen_name": "小米公司", "verified": true, "followers_count": 13930944 } ] }
Pass an id to profiles/info?uid=2202387347 for the profile and its counts. /v1 has no route that lists a profile's posts.
{ "id": "2202387347", "screen_name": "小米手机", "description": "小米手机官方微博",
"verified": true, "verified_reason": "小米手机官方微博", "followers_count": 28472525,
"friends_count": 597, "statuses_count": 29985 }
posts/detail?mid=4803377920479519 returns one post: a video by 小米公司 with reposts_count 178, comments_count 203 and attitudes_count 1152.
Read a post's comments
posts/comments?mid=4803377920479519 returns the first page, 17 of the post's 203 comments (total_number). Two are shown with the commenter's fields replaced.
{ "id": "<comment id>", "text_raw": "加油小米[打call]", "created_at": "Wed Aug 17 09:01:05 +0800 2022",
"like_count": 41, "floor_number": 2, "user": { "id": "<id>", "screen_name": "User A", "verified": false } }
{ "id": "<comment id>", "text_raw": "支持小米我们也是认真的[good]", "created_at": "Wed Aug 17 09:10:14 +0800 2022",
"like_count": 24, "floor_number": 10, "user": { "id": "<id>", "screen_name": "User B", "verified": false } }
text carries emoji as <img> tags; text_raw is plain. The route has no pagination, so a post gives one page.
Save the hot list and top comments to CSV
This script writes the ranked hot-search words to one file and the 10 most-liked comments of one post to another. It sorts the comments itself and leaves out commenter names, user ids and avatars.
import csv
import os
import sys
import time
from datetime import date, datetime
import requests
BASE = "https://api.toolzerhub.com/v1/weibo"
HEADERS = {"x-api-key": os.environ["TOOLZERHUB_API_KEY"]}
def cell(value):
# Spreadsheets run text that starts with = + - or @ as a formula.
if isinstance(value, str) and value[:1] in ("=", "+", "-", "@", "\t", "\r"):
return "'" + value
return value
def get(path, params=None, tries=5):
# Retry rate limits (429) and upstream hiccups (503).
for attempt in range(tries):
r = requests.get(BASE + path, headers=HEADERS, params=params, timeout=120)
if r.status_code not in (429, 503) or attempt == tries - 1:
r.raise_for_status()
return r.json()["data"]
time.sleep(5 * (attempt + 1))
def hot_search(out):
rows = [e for e in get("/trends/hot-search")["entries"] if e["kind"] == "ranked"]
with open(out, "w", newline="", encoding="utf-8") as f:
w = csv.writer(f)
w.writerow(["rank", "word", "heat", "label"])
for e in rows:
w.writerow([e["rank"], cell(e["word"]), e["heat"] or "", e["label"] or ""])
return len(rows)
def top_comments(mid, out, top=10):
data = get("/posts/comments", {"mid": mid})
rows = sorted(data["entries"], key=lambda c: c["like_count"], reverse=True)[:top]
with open(out, "w", newline="", encoding="utf-8") as f:
w = csv.writer(f)
w.writerow(["comment_id", "created_at", "like_count", "text"])
for c in rows:
t = datetime.strptime(c["created_at"], "%a %b %d %H:%M:%S %z %Y")
w.writerow([c["id"], t.isoformat(), c["like_count"], cell(c["text_raw"])])
return len(rows), data["count"], data["total_number"]
if __name__ == "__main__":
mid = sys.argv[1]
n = hot_search(f"weibo_hot_search_{date.today()}.csv")
shown, got, total = top_comments(mid, f"weibo_top_comments_{mid}.csv")
print(f"hot search: {n} ranked words")
print(f"comments: top {shown} of {got} returned, {total} on the post")
export TOOLZERHUB_API_KEY=your_key
python weibo_export.py 4803377920479519
For the responses above it prints hot search: 50 ranked words and comments: top 10 of 17 returned, 203 on the post.
What it costs
Each route costs 1 credit per call. A daily hot-search snapshot is 30 credits a month, and the script uses 2 credits a run.
You get 100 free credits a month; $19 buys 10,000 credits that never expire, and plans for higher volume cover more posts. Get a free API key and run the script on a post id from its URL.
Weibo's own routes are the better pick if your app posts, acts for a signed-in user, or reads a user's own timeline. For the same job on another Chinese platform, see the RedNote API or search Xiaohongshu with Python. Our Developer APIs list the other platforms on the same key.
We are not affiliated with Weibo or Sina.