PyCharm运行Python3.7 Tweepy Twitter Bot遇429及TypeError错误求助
解决Twitter Bot的429限流错误与TypeError问题
看起来你的Bot遇到了两个核心问题:API限流导致的429错误,以及错误处理逻辑中的TypeError。我来一步步帮你修复这些问题:
一、先修复TypeError异常处理错误
你当前的异常处理代码错误地假设所有Tweepy错误的参数结构都是e.args[0][0]['code'],但实际上当触发429限流错误时,错误信息的结构并不符合这个格式,导致了"string indices must be integers"的报错。
Tweepy的TweepError对象其实已经提供了api_code属性来直接获取官方错误码,我们可以直接用这个属性来判断错误类型,避免解析复杂的args结构:
修改findtweets函数中的异常捕获部分:
except tweepy.TweepError as e: # 使用api_code直接获取错误码,避免结构解析错误 if e.api_code == 139: print(f"Error with tweet {str(tweet.id)}: Already liked!") liked.append(tweet.id) continue if e.api_code == 88: print ("Rate limited.. Waiting 15 minutes before resuming.") time.sleep(60*15) continue # 打印完整错误信息方便后续调试 print(f"Unexpected error with tweet {str(tweet.id)}: {str(e)}")
二、解决429 API限流问题
429错误是Twitter API的限流提示,说明你的请求频率超过了平台规定的限额(不同操作有不同的15分钟窗口限额)。我们可以从以下几个方面优化:
- 延长操作间隔时间
当前代码中点赞后等待6秒、关注后等待3秒,这个间隔太短了,很容易触发限流。建议把这些间隔拉长:
api.create_favorite(id=tweet.id) print(f"Liked tweet from {tweet.user.screen_name}") time.sleep(15) # 延长到15秒 api.create_friendship(id=tweet.user.id) print(f"Followed user {tweet.user.screen_name}") time.sleep(10) # 延长到10秒 api.create_mute(id=tweet.user.id)
- 减少单次搜索的推文数量
一次搜索35条推文并批量处理,很容易在短时间内耗尽API限额。把搜索数量调低,比如改成10条:
search = tweepy.Cursor(api.search, q=query, result_type="recent", lang="en").items(10)
- 增加搜索循环的间隔
把全局的delay_between_search从30秒改成更大的值,比如60秒:
delay_between_search = 60
- 提前检查Rate Limit状态
在执行操作前,先获取当前的API剩余限额,避免盲目发送请求:
def findtweets(): # 先检查当前的Rate Limit状态 try: limits = api.rate_limit_status() # 获取点赞操作的剩余限额 fav_remaining = limits['resources']['favorites']['/favorites/create']['remaining'] # 获取关注操作的剩余限额 follow_remaining = limits['resources']['friends']['/friends/create']['remaining'] if fav_remaining <= 5 or follow_remaining <=5: print(f"Approaching rate limits: {fav_remaining} likes left, {follow_remaining} follows left. Waiting 10 minutes.") time.sleep(60*10) except tweepy.TweepError as e: print(f"Failed to check rate limits: {str(e)}") # 后续的搜索和处理逻辑...
三、优化其他潜在问题
- 循环中修改列表的问题
在unfollow和unfollow_friends函数中,直接在循环里调用followed.remove(user)会导致循环异常(因为列表长度在循环中变化)。建议先收集要移除的用户,再批量移除:
def unfollow(): print(" ~ Starting unfollow process ~ ") users_to_remove = [] for user in followed: try: status = api.show_friendship(source_screen_name=handle, target_id=user) except tweepy.TweepError as e: if e.api_code == 88: print ("Rate Limit Exceeded. Waiting 15 minutes.") time.sleep(900) status = api.show_friendship(source_screen_name=handle, target_id=user) else: print(f"Error checking friendship for {user}: {str(e)}") continue if not status[1].following: try: api.destroy_friendship(id=user) time.sleep(10) print(f"Unfollowed: {user}") users_to_remove.append(user) except tweepy.TweepError as e: print(f"Could not unfollow {user}: {str(e)}") else: friends.append(user) print(f"Added to friends list: {user}") users_to_remove.append(user) # 批量移除已处理的用户 for user in users_to_remove: if user in followed: followed.remove(user)
- 更明确的文件异常处理
当前的文件读取部分只捕获了笼统的异常,建议针对FileNotFoundError单独处理,让日志更清晰:
if first_run == 0: # 处理followed_users.txt try: with open('followed_users.txt') as f: followed = f.read().splitlines() if len(followed) > 100: unfollow() except FileNotFoundError: print("followed_users.txt not found - will create on first run.") # 处理liked_tweets.txt try: with open('liked_tweets.txt') as f: liked = f.read().splitlines() if len(liked) > 100: unlike() except FileNotFoundError: print("liked_tweets.txt not found - will create on first run.") # 处理friend_users.txt try: with open('friend_users.txt') as f: friends = f.read().splitlines() if len(friends) > 100: unfollow_friends() except FileNotFoundError: print("friend_users.txt not found - will create on first run.") first_run = 1
按照这些修改后,你的Bot应该能避免这两个错误,更稳定地运行。记得在测试时观察日志,根据实际的限流提示再调整间隔时间哦。
内容的提问来源于stack exchange,提问作者D_liv07
相关产品推荐
相关产品推荐

