问答
twscrape 报 No active accounts、账号一直被锁,还有别的办法吗?
简短回答
把账号池换成 API key。X 帖子搜索(每页约 20 条,$0.006)替代 twscrape 的 search,X 账号帖子列表(每页 $0.006)替代 user_tweets,不用登录 X、不用 Cookie 和代理。搜索拿 1,000 条帖子共 $0.30。
很常见的情况:每晚用 twscrape 跑 40 个关键词,X 锁了两个号,剩下的号又撞上频率限制,日志最后一行是 No active accounts。再买号、再加代理,能撑几个星期。如果任务只是读公开的帖子和账号信息,可以把账号池整个拿掉,改用 API key 调接口。你这边没有任何账号登录 X,也就没有号可以被锁。
方法对照
| twscrape | okdata 接口 | 价格 |
|---|---|---|
api.search(query) |
X 帖子搜索 | 每页 $0.006 |
api.user_tweets(uid) |
X 账号帖子列表 | 每页 $0.006 |
api.user_by_login(login) |
X 账号信息 | $0.001 |
api.tweet_details(id) |
X 帖子详情 | $0.001 |
搜索的 query 和你在 X 搜索框里输入的一样,高级语法照常可用,sort 选 latest 或 top。账号相关的接口传用户名,不传数字 ID。
把搜索循环改过来
import os, requests
API = "https://api.okdata.online/v1"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
def search(query, pages=5):
cursor, posts = None, []
for _ in range(pages):
params = {"query": query, "sort": "latest"}
if cursor:
params["cursor"] = cursor
body = requests.get(f"{API}/x/posts/search", headers=H, params=params, timeout=60).json()
if body["code"] != "ok":
raise RuntimeError(f"{body['code']}: {body['message']}")
posts += body["data"]["items"]
if not body["page"]["has_more"]:
break
cursor = body["page"]["next_cursor"]
return posts
for p in search('"向量数据库" -filter:replies lang:zh'):
print(p["published_at"], p["author"]["username"], p["metrics"]["likes"], p["text"][:80])
每条帖子带 text、published_at、url、lang,作者信息里有粉丝数,metrics 里有浏览、点赞、回复(comments)、转发和书签(favorites)。
每晚跑一次要多少钱
40 个关键词各翻 3 页,一晚 120 次调用,{{cost:x.posts.search120}};按 30 天算一个月约 {{cost:x.posts.search3600}}。每页单独计费,失败不扣钱;遇到 rate_limited,返回里会告诉你等几秒再试。重试规则见错误说明。
换过来之后少了什么
- 粉丝列表、关注列表、点赞人、转发人和列表时间线,接口目录里都没有。这些 twscrape 能拿,前提是账号一直活着。
- 没有回复串接口。想看某个账号收到的回复,可以用
to:用户名搜索,一页一页翻。 - 能看到的范围和 X 对未登录公众展示的一致:受保护账号和已删除的帖子都拿不到。
如果你需要关注关系这类图数据,或者每天的量特别大,节奏控制得当的 twscrape 账号池或者 X 官方 API 依然更合适。只是跟关键词、跟账号的话,一个 key 要省心得多。完整的口碑监测流程见口碑监测方案。
更新于