提取用户时间线推文的函数重复获取200条数据的技术问题
解决Twitter API用户时间线推文重复获取的问题
嘿,这个问题我太熟了——你这是分页拉取的时候没告诉API要找更早的推文,导致每次都在重复捞最新的200条!
问题根源分析
你第一次调用api.user_timeline()拿到了最新的200条,也记录了oldest_id,但后续循环里完全没用到这个关键参数。Twitter的user_timeline接口默认只返回最新的内容,要分页拉取历史推文,必须用max_id参数指定“只返回ID小于等于这个值的推文”。另外你循环里的if len(tweets) == 1000: break逻辑也完全没用,因为你每次count设的是200,根本不可能返回1000条。
修复后的完整代码
def extract_tweets(userid): # 先拉取第一批最新的200条推文 tweets = api.user_timeline(screen_name=userid, count=200, include_rts=True, tweet_mode='extended') # 打印前3条做示例验证 for info in tweets[:3]: print('ID: {}'.format(info.id)) print(info.created_at) print(info.full_text) print('\n') all_tweets = [] all_tweets.extend(tweets) # 记录最旧推文ID,注意要减1!避免下次重复拉取最后一条 oldest_id = tweets[-1].id - 1 # 获取用户公开的总推文数 tweet_num = api.get_user(userid).statuses_count while len(all_tweets) < tweet_num: # 核心修复:添加max_id参数,拉取比当前最旧ID更早的推文 new_tweets = api.user_timeline( screen_name=userid, count=200, include_rts=True, tweet_mode='extended', max_id=oldest_id ) # 如果没有更多推文了(比如用户删除了部分推文),直接退出循环 if not new_tweets: break # 更新最旧ID,继续下一轮拉取 oldest_id = new_tweets[-1].id - 1 all_tweets.extend(new_tweets) # 整理数据并导出CSV outtweets = [ [ tweet.id_str, tweet.created_at, tweet.favorite_count, tweet.retweet_count, tweet.full_text.encode('utf-8').decode('utf-8') ] for tweet in all_tweets ] df = DataFrame(outtweets, columns=['id', 'created_at', 'favorite_count', 'retweet_count', 'text']) df.to_csv('%s_tweets.csv' % userid, index=False) # 这里加上return,不然函数执行完不会返回前3条数据 return df.head(3)
几个关键细节提醒
max_id=oldest_id - 1:Twitter API的max_id规则是返回小于等于该ID的推文,所以如果直接用之前的oldest_id,会重复拉取最后一条旧推文,减1就能完美避免这个重复问题。- 空列表判断:增加
if not new_tweets: break很重要,因为用户的statuses_count可能包含已删除的推文,实际可获取的推文数会比这个数字少,不然会无限循环。 - 变量命名优化:把循环里的
tweets改成new_tweets,避免覆盖初始的推文列表,代码可读性更高。 - 返回结果:之前的
df.head(3)只是执行但没返回,加上return后调用函数就能拿到前3条数据的预览。
内容的提问来源于stack exchange,提问作者yragab
相关产品推荐
相关产品推荐

