问答

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 要省心得多。完整的口碑监测流程见口碑监测方案。

更新于