API仕様には特に上限についての記述は見受けられませんでした。
response.linksに"last"が含まれていた時に、そのpage番号が想定と合っているかを確認してみてはいかがでしょうか。
また、stargazer[]にjsonを追加する時、別途整数値も同時にカウントアップさせて、len()の結果と齟齬がないか突き合わせてみてはいかがでしょう。
GitHubの特定のリポジトリのStarの付与履歴を全て取得したいと考えています。そこで、GitHubのREST APIを使い、以下のドキュメントを参考に取得を試みました。
ドキュメントからは把握できず、挙動からの推測ではありますが、取得可能なStarの付与履歴は40,000件までのようです。そこで、40,000件を超えるStarの付与履歴を全て取得する方法について相談させていただきたいです。また、GitHubのREST APIによって、取得可能なStarの付与履歴が40,000件までという説明があれば、教えていただきたいです。
import requests
# 対象リポジトリとREST API エンドポイント
# 参考:https://docs.github.com/ja/rest/activity/starring
owner = "pandas-dev"
repo = "pandas"
url = f"https://api.github.com/repos/{owner}/{repo}/stargazers"
# personal access token
# 参考:https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
token = "XXXXXXXXXX"
headers = {
"Accept": "application/vnd.github.v3.star+json",
"Authorization": f"token {token}",
}
params = {"per_page": 100, "page": 1}
stargazers = []
while True:
response = requests.get(url, params=params, headers=headers)
stargazers += response.json()
# 次のページが存在する場合、パラメータを更新
if "next" in response.links.keys():
params["page"] += 1
else:
break
len(stargazers)
40000
上記は以下のリポジトリについてのStarの付与履歴ですが、この件数に対して実際のStar数は42k(約42,000)件であり、不足していることが推測されます。
API仕様には特に上限についての記述は見受けられませんでした。
response.linksに"last"が含まれていた時に、そのpage番号が想定と合っているかを確認してみてはいかがでしょうか。
また、stargazer[]にjsonを追加する時、別途整数値も同時にカウントアップさせて、len()の結果と齟齬がないか突き合わせてみてはいかがでしょう。
あと、40kよりはるかに大きいレポジトリに対してはどのような値になるでしょうか。
こちらは150kほどあります。
不足具合によっては、stargazers[]がパンクしている可能性も考えられますね。
立て続けにすみません。
whileループで連続してリクエストしているので、レート制限に引っかかってる可能性もありますね。
@daikikatsuragawa
Questioner@iiokazuya
コメントいただき、ありがとうございます🙇
response.linksに"last"が含まれていた時に、そのpage番号が想定と合っているかを確認してみてはいかがでしょうか。
"last"が含まれるresponse.linksの"last"の内容を確認すると以下となります。
# 省略
params = {"per_page": 100, "page": 1}
response = requests.get(url, params=params, headers=headers)
response.links["last"]
{'url': 'https://api.github.com/repositories/858127/stargazers?per_page=100&page=400',
'rel': 'last'}
URLクエリパラメータが?per_page=100&page=400
となっていて、そもそも取得可能なStarの付与履歴は40,000件(100×400)ということになりそうですね…やはりGitHubのREST APIの仕様(限界)のような気もしてきました。
また、stargazer[]にjsonを追加する時、別途整数値も同時にカウントアップさせて、len()の結果と齟齬がないか突き合わせてみてはいかがでしょう。
こちらは、一致するため、取得可能なStarの付与履歴は40,000件という状況下では齟齬のない結果となっています。
# 省略
stargazers = []
count = 0
while True:
response = requests.get(url, params=params, headers=headers)
stargazers += response.json()
count =+ 1
# 次のページが存在するか否かを確認
if "next" in response.links.keys():
params["page"] += 1
else:
break
len(stargazers) == count * 100
True
あと、40kよりはるかに大きいレポジトリに対してはどのような値になるでしょうか。
https://github.com/microsoft/vscode
こちらは150kほどあります。
不足具合によっては、stargazers[]がパンクしている可能性も考えられますね。
こちらも同様に、取得可能なStarの付与履歴は40,000件でした。
立て続けにすみません。
whileループで連続してリクエストしているので、レート制限に引っかかってる可能性もありますね。
タイミングを空けて再実行しても同じなので、これは問題なさそうです。
なるほど、どうも40,000件というのが、何か定められたもののようですね。
GitHubのデータベースをパンクさせないように、リポジトリごとに40,000件以前の履歴は捨ててる可能性もありますね。(件数だけは記憶している)
@daikikatsuragawa
Questionerなるほど、どうも40,000件というのが、何か定められたもののようですね。
おそらくそうだと思っています。
GitHubのデータベースをパンクさせないように、リポジトリごとに40,000件以前の履歴は捨ててる可能性もありますね。(件数だけは記憶している)
参考までにですが、「4,0000件以降の履歴を取得できない」が正しそうです。正確には以下だけで断定はできないのですが、ここ取得できた履歴の最新の日付が半年ほど前のもので、この規模のリポジトリのStarが半年ほどつかない可能性は低そうで、最古〜4,0000件までの履歴を取得しているようです。
# 省略
max([stargazer["starred_at"] for stargazer in stargazers])
2023-11-15T17:18:58Z
参考までに、他のツール(Webアプリケーション)を確認してみたところ、この半年でもStarは追加されていそうです。