问答

微博和 B 站评论的 IP 属地,能通过接口拿到吗?

简短回答

能。B 站视频评论接口返回的每条评论都带 ip_location,每页约 20 条,$0.002。微博要加 view=full:微博搜索会把每条微博的发布地放在 ext.region(每页 $0.002),账号信息会把账号的 IP 属地放在 ext.ip_location(每个 $0.002)。

一家成都的火锅连锁在上海开出第一批门店,在 B 站发了一条开业视频。市场部想知道评论区的热闹,到底是上海本地人在期待,还是散在各地、想家的四川人在起哄。两个平台都会在公开内容上显示 IP 属地,这个字段可以成批拿来统计。

字段在哪里

平台 接口 字段 粒度
B 站 B站视频评论 每条评论的 ip_location 每条评论
微博 微博搜索,加 view=full 每条微博的 ext.region 每条微博
微博 微博账号信息,加 view=full ext.ip_location 每个账号

取值就是平台页面上显示的地名,一般到省,比如上海、四川;海外用户显示国家。IP属地、发布于这类前缀已经去掉了。

费用

任务 调用次数 费用
1,000 条 B 站评论 50 $0.10
1,000 条微博 100 $0.20
200 个微博账号资料 200 $0.40

按省份计数

import os, requests
from collections import Counter

API = "https://api.okdata.online"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}

def pages(path, n, **p):
    cursor = None
    for _ in range(n):
        r = requests.get(API + path, headers=H, timeout=30,
                         params={**p, **({"cursor": cursor} if cursor else {})}).json()
        if r["code"] != "ok":
            print(path, r["code"]); return
        yield from r["data"]["items"]
        if not r["page"]["has_more"]:
            return
        cursor = r["page"]["next_cursor"]

bili = Counter(c["ip_location"] for c in pages("/v1/bilibili/videos/comments/list", 25,
               id="BV1xx411c7mD", sort="latest", fields="ip_location"))
weibo = Counter(p["ext"].get("region") for p in pages("/v1/weibo/posts/search", 50,
                query="成都火锅 上海", view="full", fields="ext.region"))
print("B站", bili.most_common(10))
print("微博", weibo.most_common(10))

解读时要小心

  • 它反映的是发言时 IP 所在的地方,不等于这个人住在哪。出差、旅行、VPN、手机漫游都会让它变。
  • 平台开始显示属地之前的老微博、老评论没有这个字段。缺失时返回 null,并写在 meta.unavailable 里。
  • 只做汇总统计。1,000 条评论的省份分布是市场研究;盯着某一个人的位置不是该做的事。
  • 微博评论不在接口目录里,所以微博这边能拿到的是微博本身和账号的属地,拿不到回复的属地。

其他办法

如果是自己的视频,B 站创作中心能看到观众的地域分布,微博的账号数据分析也能看粉丝地域。这些数字连不评论的观众也算进去,看自己的账号时更准。看竞品的内容,就只能靠上面这些公开字段。更多读懂公众反应的方法,见口碑监测方案。

更新于