如何避免使用Tweepy获取Retweets时出现TooManyRequests错误
问题
从tweetlist.csv文件提取tweet.id列生成tweet_ids列表,使用Tweepy获取该列表中推文的所有转推时触发了**TooManyRequests(429请求过多)**错误,以下是代码及报错信息:
代码
import re import pandas as pd from textblob import TextBlob df1 = pd.DataFrame(columns=('id_str','in_reply_to_status_id','in_reply_to_user_id', 'in_reply_to_screen_name','user','is_quote_status', 'tweet_text', 'tweet_sentiment', 'user_followers_count', 'user_friends_count', 'user_account_age', 'user_verified', 'user_favourites_count', 'user_tweets', 'tweet_retweeted', 'tweet_retweet_count', 'tweet_favorite_count')) df1.sort_values("tweet_text", inplace = True) df1.drop_duplicates(subset ="tweet_text", keep = False, inplace = True) for tweet_id in tweet_ids: retweet_list = api.get_retweets(tweet_id,count=10) length = len(retweet_list) if(length > 0 ): for tweet in retweet_list: sentimentText = TextBlob(tweet.text) df1 = df1.append({'id_str': tweet.id_str, 'in_reply_to_status_id': tweet.in_reply_to_status_id, 'in_reply_to_user_id': tweet.in_reply_to_status_id, 'in_reply_to_screen_name': tweet.in_reply_to_screen_name, 'user': tweet.user.id, 'is_quote_status': tweet.is_quote_status, 'tweet_text': re.sub(r'http\S+', '', tweet.text), # Removing any URL's in the tweet text here 'tweet_sentiment': sentimentText.sentiment.polarity, 'user_followers_count': tweet.user.followers_count, 'user_friends_count': tweet.user.friends_count, 'user_account_age': tweet.user.created_at, 'user_verified': tweet.user.verified, 'user_favourites_count': tweet.user.favourites_count, 'user_tweets': tweet.user.statuses_count, 'tweet_retweeted': tweet.retweeted, 'tweet_retweet_count': tweet.retweet_count, 'tweet_favorite_count': tweet.favorite_count}, ignore_index=True) df1.head()
报错信息
--------------------------------------------------------------------------- TooManyRequests Traceback (most recent call last) <ipython-input-23-2ae54f6fa723> in <module> 17 for tweet_id in tweet_ids: 18 ---> 19 retweet_list = api.get_retweets(tweet_id,count=10) 20 21 length = len(retweet_list) C:\ProgramData\Anaconda3\lib\site-packages\tweepy\api.py in wrapper(*args, **kwargs) 44 kwargs['payload_list'] = payload_list 45 kwargs['payload_type'] = payload_type ---> 46 return method(*args, **kwargs) 47 wrapper.payload_list = payload_list 48 wrapper.payload_type = payload_type C:\ProgramData\Anaconda3\lib\site-packages\tweepy\api.py in get_retweets(self, id, **kwargs) 816 'GET', f'statuses/retweets/{id}', endpoint_parameters=( 817 'count', 'trim_user' --> 818 ), **kwargs 819 ) 820 C:\ProgramData\Anaconda3\lib\site-packages\tweepy\api.py in request(self, method, endpoint, endpoint_parameters, params, headers, json_payload, parser, payload_list, payload_type, post_data, files, require_auth, return_cursors, upload_api, use_cache, **kwargs) 261 raise NotFound(resp) 262 if resp.status_code == 429: --> 263 raise TooManyRequests(resp) 264 if resp.status_code >= 500: 265 raise TwitterServerError(resp) TooManyRequests: 429 Too Many Requests 88 - Rate limit exceeded
解决方案
Twitter API对statuses/retweets/:id端点(对应api.get_retweets)的限制为每15分钟最多75次请求,429错误就是短时间内请求次数超限导致的,以下是可行的解决方法:
1. 开启Tweepy内置的速率限制等待
初始化API时添加wait_on_rate_limit参数,Tweepy会自动在超限后等待到限制重置再继续请求:
# 初始化API时配置参数 api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
wait_on_rate_limit_notify=True会在等待时打印提示,方便跟踪进度。
2. 手动控制请求间隔
如果不想依赖内置机制,可手动计算请求间隔:每15分钟75次请求,平均每次间隔至少12秒(15*60/75=12),用time.sleep()添加延迟:
import time for tweet_id in tweet_ids: retweet_list = api.get_retweets(tweet_id, count=10) # 处理数据逻辑... time.sleep(12) # 每次请求后等待12秒
注意如果有其他API请求,需统一计算总请求量,避免超限。
3. 优化代码提升效率
你的代码存在两个可优化点:
- 替换
df.append()为列表收集数据:append是低效操作,建议先把数据存入列表,最后一次性生成DataFrame:
# 初始化空列表存储数据 data_list = [] for tweet_id in tweet_ids: retweet_list = api.get_retweets(tweet_id, count=10) if retweet_list: for tweet in retweet_list: sentimentText = TextBlob(tweet.text) data_dict = { 'id_str': tweet.id_str, 'in_reply_to_status_id': tweet.in_reply_to_status_id, 'in_reply_to_user_id': tweet.in_reply_to_user_id, # 修正原代码的字段赋值错误 'in_reply_to_screen_name': tweet.in_reply_to_screen_name, 'user': tweet.user.id, 'is_quote_status': tweet.is_quote_status, 'tweet_text': re.sub(r'http\S+', '', tweet.text), 'tweet_sentiment': sentimentText.sentiment.polarity, 'user_followers_count': tweet.user.followers_count, 'user_friends_count': tweet.user.friends_count, 'user_account_age': tweet.user.created_at, 'user_verified': tweet.user.verified, 'user_favourites_count': tweet.user.favourites_count, 'user_tweets': tweet.user.statuses_count, 'tweet_retweeted': tweet.retweeted, 'tweet_retweet_count': tweet.retweet_count, 'tweet_favorite_count': tweet.favorite_count } data_list.append(data_dict) # 最后一次性生成DataFrame并去重排序 df1 = pd.DataFrame(data_list) df1.sort_values("tweet_text", inplace=True) df1.drop_duplicates(subset="tweet_text", keep=False, inplace=True)
- 修正字段错误:原代码中
in_reply_to_user_id被错误赋值为tweet.in_reply_to_status_id,上述代码已修正。
4. 升级API权限
如果需要处理大量推文,免费版API的速率限制可能不够,可以考虑升级到Twitter付费API计划,获取更高的请求额度。
内容的提问来源于stack exchange,提问作者hilal saim
相关产品推荐
相关产品推荐

