如何在不达到github API使用限制的情况下获取所有用户的位置

时间:2013-06-16 21:28:42

标签: python github github-api github3.py

目前我正在尝试获取所有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个小时以上)。有人可以为我提供更好的方法吗?

1 个答案:

答案 0 :(得分:1)

因此,如果您使用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来分隔您的请求。超过3600秒的5000个请求是每秒1.389个请求。如果每个请求需要半秒钟(我认为这是个人的低估),你可以做

import time

for user in g.iter_all_users(per_page=200):
    user.refresh()
    #: other logic
    time.sleep(0.5)

这将确保每秒发出一个请求,并且您从未达到ratelimit。无论如何,它相当蹩脚。

将来,我会使用用户的id作为数据库中的id将这些值存储在数据库中,然后只查找max并尝试从那里开始。我必须检查/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

第二个迭代器应该为你提供自上次请求中最后一个用户以来的所有新用户,如果我没记错的话,但我现在非常累,所以我记得错了。