我正在使用 python 中的 tweepy 库和 requests 库的组合来抓取喜欢某些推文及其位置的用户(对于那些公开披露的用户)。为了避免速率限制,我一直为我的 tweepy API 设置 wait_on_rate_limit=True ,并且这一直有效。
但是,为了获取用户的位置,我必须使用 requests 库,并且它经常在抓取帖子用户的过程中超出速率限制,在我的函数返回值之前返回错误。这是代码:
def get_user_location(id):
BEARER_TOKEN = "my_bearer_token"
endpoint = f'https://api.twitter.com/2/users/{id}'
headers = {'authorization': f'Bearer {BEARER_TOKEN}'}
params = {
'user.fields': 'location',
}
response = requests.get(endpoint,
params=params,
headers=headers) # send the request
if "location" in response.json()["data"].keys():
return response.json()["data"]["location"]
return None
我浏览了文档,找不到任何有关可以传递到 requests.get 调用中的参数的信息,以使我的程序等待继续执行,直到速率限制冷却结束。有谁知道我可以让我的应用程序等到速率限制重置,这样它就不会返回速率限制错误?
requests
库中没有内置功能可以像 tweepy
那样处理速率限制。您可以实现自定义重试机制来检查 API 返回的 HTTP 状态代码。如果状态代码指示已超出速率限制(状态代码 429),则该函数可以在重试请求之前暂停 Retry-After 标头中指定的持续时间。
import requests
import time
def get_user_location(id):
BEARER_TOKEN = "my_bearer_token"
endpoint = f'https://api.twitter.com/2/users/{id}'
headers = {'authorization': f'Bearer {BEARER_TOKEN}'}
params = {
'user.fields': 'location',
}
while True:
response = requests.get(endpoint, params=params, headers=headers)
if response.status_code == 429: # Rate limit exceeded
reset_time = int(response.headers.get("x-rate-limit-reset"))
current_time = int(time.time())
wait_time = max(reset_time - current_time, 0)
print(f"Rate limit exceeded. Retrying after {wait_time} seconds.")
time.sleep(wait_time)
continue
if response.status_code == 200:
if "location" in response.json().get("data", {}):
return response.json()["data"]["location"]
return None
response.raise_for_status() # Raise an exception for other HTTP errors