目前我正试图获得所有Github用户位置。我使用github3 python库来获取位置。但是当我的api调用超过5K时,它会给我带来api过度使用错误。这是我的代码。
import github3
from datetime import datetime
import sys
def main(pswd):
g = github3.login(username="rakeshcusat", password=pswd)
current_time = datetime.now()
fhandler = open("githubuser_"+current_time.strftime("%d-%m-%y-%H:%M:%S"), "w")
for user in g.iter_all_users():
user.refresh()
try:
fhandler.write(" user: {0}, email: {1}, location: {2}n".format(str(user), str(user.email), str(user.location)))
except:
print "Something wrong, user id : {0}".format(user.id);
fhandler.close()
if __name__ == "__main__":
if len(sys.argv) == 2:
main(sys.argv[1])
else:
print "Please provide your password"
我可以通过下载所有用户名首先,这将只是一个API调用做到这一点。然后迭代下载用户位置。如果遇到过度使用,则等待一个小时并在api调用离开的地方恢复它。但这似乎是一个蹩脚的解决方案,肯定会花费更多的时间(大约25个多小时)。有人能给我提供更好的方法吗?
所以如果你使用的是github3.py的开发版本,你可以使用per_page参数,例如
for user in g.iter_all_users(per_page=200):
user.refresh()
#: other logic
问题是,你将使用per_page
保存7个请求(如果我没记错的话,1个请求现在返回25个,所以你将在1中得到相当于8个请求)。问题是你然后使用User#refresh
相当快地使用200个请求。为了避免速率限制,您可以在代码中使用sleep来分隔请求。5000个请求在3600秒内分割,即每秒1.389个请求。如果每个请求需要半秒(我个人认为这是低估了),您可以执行
import time
for user in g.iter_all_users(per_page=200):
user.refresh()
#: other logic
time.sleep(0.5)
这将确保每秒发出一个请求,并且您永远不会达到速率限制。不管怎样,它相当蹩脚。
在将来,我会使用用户的id作为数据库中的id将这些值存储在数据库中,然后只是寻找最大值并尝试从那里开始。我必须检查/users
是否支持类似于since
参数的东西。或者,您也可以像这样操作
import time
i = g.iter_all_users(per_page=200):
for user in i:
user.refresh()
#: other logic
time.sleep(0.5)
# We have all users
# store i.etag somewhere then later
i = g.iter_all_users(per_page=200, etag=i.etag)
for user in i:
user.refresh()
#: etc
如果我没记错的话,第二个迭代器应该会给你上次请求中最后一个用户以来的所有新用户,但我现在很累,所以我可能记错了什么