Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Python从Github API中的所有页面获取数据?_Python_Api_Github_Pagination_Python Requests - Fatal编程技术网

如何使用Python从Github API中的所有页面获取数据?

如何使用Python从Github API中的所有页面获取数据?,python,api,github,pagination,python-requests,Python,Api,Github,Pagination,Python Requests,我正在尝试导出回购列表,它总是会向我返回有关第一页的信息。我可以使用URL+“?per_page=100”扩展每页的项目数,但这还不足以获得整个列表。 我需要知道如何获取从第1页、第2页、…、第N页提取数据的列表。 我正在使用请求模块,如下所示: while i <= 2: r = requests.get('https://api.github.com/orgs/xxxxxxx/repos?page{0}&per_page=100'.format(i), auth=(

我正在尝试导出回购列表,它总是会向我返回有关第一页的信息。我可以使用URL+“?per_page=100”扩展每页的项目数,但这还不足以获得整个列表。 我需要知道如何获取从第1页、第2页、…、第N页提取数据的列表。 我正在使用请求模块,如下所示:

while i <= 2:
      r = requests.get('https://api.github.com/orgs/xxxxxxx/repos?page{0}&per_page=100'.format(i), auth=('My_user', 'My_passwd'))
      repo = r.json()
      j = 0
      while j < len(repo):
            print repo[j][u'full_name']
            j = j+1
      i = i + 1
import requests
url = 'https://api.github.com/orgs/xxxxxxx/repos?page{0}&per_page=100'
response = requests.get(url)
link = response.headers.get('link', None)
if link is not None:
    print link
而我来自:

答复:

Status: 200 OK
Link: <https://api.github.com/resource?page=2>; rel="next",
      <https://api.github.com/resource?page=5>; rel="last"
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4999
它是一个包含响应头的字典。如果存在链接,则会有更多页面,其中将包含相关信息。建议使用这些链接进行遍历,而不是构建自己的链接

您可以尝试以下方法:

while i <= 2:
      r = requests.get('https://api.github.com/orgs/xxxxxxx/repos?page{0}&per_page=100'.format(i), auth=('My_user', 'My_passwd'))
      repo = r.json()
      j = 0
      while j < len(repo):
            print repo[j][u'full_name']
            j = j+1
      i = i + 1
import requests
url = 'https://api.github.com/orgs/xxxxxxx/repos?page{0}&per_page=100'
response = requests.get(url)
link = response.headers.get('link', None)
if link is not None:
    print link

如果link不是None,它将是一个包含资源相关链接的字符串。

根据我的理解,如果只返回一页数据,则link将是None,否则,即使超出最后一页,链接也将存在。在这种情况下,链接将包含以前和第一个链接

下面是一些示例python,其目的是简单地返回下一页的链接,如果没有下一页,则返回None。因此可以合并到一个循环中

link = r.headers['link']
if link is None:
    return None

# Should be a comma separated string of links
links = link.split(',')

for link in links:
    # If there is a 'next' link return the URL between the angle brackets, or None
    if 'rel="next"' in link:
        return link[link.find("<")+1:link.find(">")]
return None
link=r.headers['link']
如果链接为“无”:
一无所获
#应该是以逗号分隔的链接字符串
links=link.split(',')
对于链接中的链接:
#如果有“下一个”链接,则返回尖括号之间的URL,或者不返回
如果链接中的“rel=”next“:
返回链接[link.find(“”)]
一无所获
如果您没有制作一个完整的应用程序,请使用“个人访问令牌”


在上述答案的基础上,这里有一个递归函数来处理GitHub分页,它将遍历所有页面,将列表与每个递归调用连接起来,最后在没有更多页面可检索时返回完整的列表,除非可选故障保护在超过500项时返回列表

import requests

api_get_users = 'https://api.github.com/users'


def call_api(apicall, **kwargs):

    data = kwargs.get('page', [])

    resp = requests.get(apicall)
    data += resp.json()

    # failsafe
    if len(data) > 500:
        return (data)

    if 'next' in resp.links.keys():
        return (call_api(resp.links['next']['url'], page=data))

    return (data)


data = call_api(api_get_users)
首先你使用

print(a.headers.get('link'))
这将提供存储库的页数,如下所示

<https://api.github.com/organizations/xxxx/repos?page=2&type=all>; rel="next", 

<https://api.github.com/organizations/xxxx/repos?page=8&type=all>; rel="last"
;rel=“下一步”,
; rel=“last”
从这里你可以看到,目前我们在回购协议的第一页,rel='next'表示下一页是2,rel='last'表示你的最后一页是8

在知道要遍历的页数之后,您只需要在获取请求时对页码使用“=”,并将while循环更改为最后一个页码,而不是len(repo),因为它每次将返回100。 例如

i=1

当我打印每次迭代中生成的
url
并检查它是否正确时,您有一行:
repo=p.json()
这是打字错误吗?应该读
r.json()
?谢谢你的回答,但我已经在github文档中找到了,我不知道它是如何工作的。我找不到使用python实现它的方法。你能帮帮我吗?是的,我正在检查。你有一个有很多页面的组织吗?我是一个使用API和Python的初学者,非常感谢你的帮助。我有一个拥有44个用户和190个repo的组织,因此不可能一次下载所有用户,因为最多有100个项目。只需检查headers dict是否包含关键链接,在这种情况下,您可以找到下一个请求并执行该操作,直到它不显示。我不知道如何执行。我可以和你联系以了解一些东西吗?如果被接受的答案被测试得更好的话,我想我会很快通过聊天来帮助你。这就解决了两种不同的情况,如果它能适应这样的情况,那就更好了:
data=call_-api(…);而数据:#用数据做点什么;数据=调用api(…)
。基本上是要有某种迭代器,允许您批量检索数据,一次一页:)谢谢!我不知道有响应。links属性。需要选择此答案作为最佳答案。其他任何解决方案都是黑客!
i=1
while i <= 8:
      r = requests.get('https://api.github.com/orgs/xxxx/repos?page={0}&type=all'.format(i),
                         auth=('My_user', 'My_passwd'))
      repo = r.json()
      for j in repo:
        print(repo[j][u'full_name'])
      i = i + 1
        link = res.headers.get('link', None)

        if link is not None:
            link_next = [l for l in link.split(',') if 'rel="next"' in l]
            if len(link_next) > 0:
                return int(link_next[0][link_next[0].find("page=")+5:link_next[0].find(">")])