1

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

4

1 回答 1

2

所以如果你使用 github3.py 的开发版本,你可以使用 per_page 参数,例如,

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

问题是,您将保存 7 个请求per_page(如果我没记错的话,1 个请求现在返回 25 个,因此您将在 1 个请求中获得相当于 8 个请求)。问题是您随后使用 200 个请求相当快User#refresh。为了避免速率限制,您可以做的是在代码中使用 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)

这将确保每秒发出一个请求,并且您永远不会达到速率限制。无论如何,它是相当蹩脚的。

将来,我会使用用户的 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

如果我没记错的话,第二个迭代器应该会为您提供自上次请求中的最后一个用户以来的所有新用户,但我目前很累,所以我可能记错了。

于 2013-06-21T03:54:49.130 回答