Почему разбиение на страницы GitHub дает разные результаты?
Если я выполняю поиск кода с помощью GitHub Search API и запрашиваю 100 результатов на страницу, я получаю различное количество результатов:
import requests
# url = "https://api.github.com/search/code?q=torch +in:file + language:python+size:0..250&page=1&per_page=100"
url = "https://api.github.com/search/code?q=torch +in:file + language:python&page=1&per_page=100"
headers = {
'Authorization': 'Token xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
}
response = requests.request("GET", url, headers=headers).json()
print(len(response['items']))
Благодаря этому ответу у меня есть следующий обходной путь: я запускаю запрос несколько раз, пока не получу требуемые результаты на странице.
Мой текущий проект требует, чтобы я перебирал поисковый API в поисках файлов разного размера. Я в основном повторяю описанную здесь процедуру . Поэтому мой код выглядит примерно так:
url = "https://api.github.com/search/code?q=torch +in:file + language:python+size:0..250&page=1&per_page=100"
В этом случае я не знаю заранее, сколько результатов должна иметь страница. Может ли кто-нибудь сказать мне обходной путь для этого? Может быть, я неправильно использую API поиска?
1 ответ
GitHub предоставляет документацию об использовании разбиения на страницы в REST API. Каждый ответ включает заголовок, содержащий ссылку на следующий набор результатов (наряду с другими ссылками); вы можете использовать это для перебора всего набора результатов.
Для конкретного поиска, который вы выполняете («каждый файл Python, содержащий слово «факел»»), вы довольно быстро столкнетесь с ограничениями скорости, но, например, следующий код будет перебирать результаты, 10 за раз (или около того), пока не будет прочитано 50 или более результатов:
import os
import requests
import httplink
url = "https://api.github.com/search/code?q=torch +in:file + language:python&page=1&per_page=10"
headers = {"Authorization": f'Token {os.environ["GITHUB_TOKEN"]}'}
# This is the total number of items we want to fetch
max_items = 50
# This is how many items we've retrieved so far
total = 0
try:
while True:
res = requests.request("GET", url, headers=headers)
res.raise_for_status()
link = httplink.parse_link_header(res.headers["link"])
data = res.json()
for i, item in enumerate(data["items"], start=total):
print(f'[{i}] {item["html_url"]}')
if "next" not in link:
break
total += len(data["items"])
if total >= max_items:
break
url = link["next"].target
except requests.exceptions.HTTPError as err:
print(err)
print(err.response.text)
Здесь я используюhttplink
модуль для разбораLink
заголовок, но вы можете сделать то же самое с соответствующим регулярным выражением иre
модуль.