Answers
How do I monitor Weibo for new posts mentioning my brand?
Short answer
Run Weibo post search with sort=latest for each brand keyword every hour, and stop paging as soon as you reach a post you already stored. A page holds about 10 posts and costs $0.002, so 3 keywords checked hourly at 2 pages each (144 calls) cost $0.288 a day.
Say you run social for a skincare brand. You want every new Weibo post that names the brand or its two best-selling products in one sheet each morning, with reposts and likes, so the team can thank fans, answer complaints and spot a problem early. That is a keyword search sorted by newest first, run on a schedule, that remembers what it has already seen.
The endpoint
Weibo post search takes query and sort. With sort=latest you get the newest matching posts first, about 10 per page, each with text, time, author (ID, name, followers, verified), likes, comments, reposts, images and hashtags. Pass page.next_cursor back as cursor for the next page; each page is billed on its own.
What a day costs
| Brand volume | Pages per keyword per hour | Calls a day (3 keywords) | Cost a day |
|---|---|---|---|
| Quiet | 1 | 72 | $0.144 |
| Typical | 2 | 144 | $0.288 |
| Busy launch week | 5 | 360 | $0.72 |
Most hours you stop after the first page, because the second page is already old news. The early stop is where the savings come from.
The monitor
import json, os, requests
URL = "https://api.okdata.online/v1/weibo/posts/search"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
KEYWORDS = ["山野护肤", "山野精华", "山野防晒"]
MAX_PAGES = 5
seen = set(open("seen.txt").read().split()) if os.path.exists("seen.txt") else set()
new = []
for kw in KEYWORDS:
cursor = None
for _ in range(MAX_PAGES):
params = {"query": kw, "sort": "latest", **({"cursor": cursor} if cursor else {})}
r = requests.get(URL, headers=H, params=params, timeout=30).json()
if r["code"] != "ok":
print(kw, r["code"], r["message"]); break
fresh = [p for p in r["data"]["items"] if p["id"] not in seen]
new += fresh
seen.update(p["id"] for p in fresh)
if len(fresh) < len(r["data"]["items"]) or not r["page"]["has_more"]:
break # reached posts we already have
cursor = r["page"]["next_cursor"]
with open("mentions.jsonl", "a", encoding="utf-8") as f:
for p in new:
f.write(json.dumps(p, ensure_ascii=False) + "\n")
open("seen.txt", "w").write("\n".join(seen))
Limits worth knowing
- Search returns what Weibo's search chooses to show. Posts from restricted accounts, or posts Weibo hides from search, never appear, so treat this as a strong sample, not a complete record.
- Short brand names match inside unrelated words in Chinese. Add a product word to the query, or filter the results before anyone reads them.
- Long posts can come back cut short; with
view=full,ext.is_long_textmarks them. The catalog has no single-post lookup, so open the post'surlto read the rest. - Comments and a user's own timeline are not in the catalog. If you need the replies under a complaint, read them on Weibo.
Other ways
Social listening platforms bundle this with sentiment dashboards and suit teams that want reports, not scripts. For a one-off deep crawl that includes comments, an open-source crawler such as MediaCrawler run with your own Weibo login does more, at the cost of maintaining the cookie. Under ten mentions a day, the Real-time tab of Weibo search read by hand is enough. More on the whole workflow: word of mouth.
Updated