问答
怎么监控微博上提到我们品牌的新微博?
简短回答
每小时对每个品牌词跑一次微博搜索,sort=latest,翻到已经存过的微博就停。每页约 10 条,$0.002;3 个关键词、每小时各翻 2 页,一天 144 次调用,共 $0.288。
假设你负责一个护肤品牌的社媒。每天早上,你希望在一张表里看到前一天所有提到品牌名或两款主打产品的新微博,带转发和点赞数,团队好去感谢用户、回应吐槽,问题刚冒头就能看见。落到技术上,就是一个按最新排序的关键词搜索,定时跑,并且记得哪些已经看过。
用哪个接口
微博搜索有两个主要参数:query 和 sort。sort=latest 时最新的微博排在前面,每页约 10 条,每条带正文、发布时间、作者(ID、昵称、粉丝数、是否认证)、点赞、评论、转发、图片和话题。下一页把 page.next_cursor 作为 cursor 传回去,每一页单独计费。
一天要花多少
| 品牌声量 | 每词每小时翻几页 | 每天调用(3 个词) | 每天费用 |
|---|---|---|---|
| 平时很安静 | 1 | 72 | $0.144 |
| 一般 | 2 | 144 | $0.288 |
| 新品发布周 | 5 | 360 | $0.72 |
大部分时候翻完第一页就停了,因为第二页已经是看过的内容。省钱主要就靠这个提前停。
监控脚本
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 # 已经翻到存过的微博
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))
需要心里有数的地方
- 搜索结果是微博搜索愿意展示的那部分。受限账号发的、被微博从搜索里隐藏的微博都不会出现,所以把它当成一份质量很高的样本,别当成全量。
- 中文里短的品牌名很容易匹配到不相干的词。查询词里加上产品词,或者在给人看之前先过滤一遍。
- 长微博在搜索结果里可能被截断,加
view=full后ext.is_long_text会标出来。接口目录里没有单条微博详情,要看全文就打开它的url。 - 评论和某个用户自己的微博列表都不在接口目录里。投诉下面的回复,需要去微博上看。
其他办法
商业舆情平台把这件事和情感分析看板打包在一起,适合要报表、不想维护脚本的团队。如果是一次性深挖、还要连评论一起抓,用 MediaCrawler 这类开源爬虫配上你自己的微博登录态能拿到更多,代价是要一直维护 Cookie。每天提及不到十条的话,在微博搜索的实时标签下手动看就够了。完整思路见口碑监测方案。
更新于