Python脚本爬取两千条Github开源仓库
本人所从事的研究方向是软件自动化测试,其中需要用到深度学习技术,具体的来说是一款由Google公司开发的强大的文本生成模型–GPT2模型,具体使用方法详见另外一篇博客。其中模型的训练需要大量的数据,而数据来源选择从Github网站上爬取star排名前两千的JavaScript项目。
- 详细的API接口信息
Github作为一个出色的代码托管平台,也为开发者们提供了结构非常清晰的API接口信息,浏览器安装json插件后阅读更佳。 - 详细的开发者文档
最好的学习方式就是阅读官方文档 - 注意事项
- GitHub Search API每次搜索最多提供1,000个结果。
- 对于认证用户,每分钟最多可以进行30次请求, 对于未认证用户,每分钟最多可以进行10次请求。
- 默认每页的显示结果是30条,可通过
per_page
参数指定,最多不超过100条。
- 爬取目标
Github开源仓库中star排名前2000的JavaScript语言仓库地址。 - 思路流程
- 指定搜索的关键字
language, per_page, sort
等; - 添加Authentication认证和Page分页;
- 为了解决每页最多只有100条信息,每次搜索最多只能展示1000条结果的问题,需要将请求以
stars
关键字分散开来。 - 编写代码实现。
- 指定搜索的关键字
- 其中遇到的问题
-
Authentication认证,可采用两种方法:
此处采用令牌访问方式。那么如何获取令牌呢?在你的个人主页setting/ Developer settings/personal access token/generate new token
,把生成的token复制保存下来,后面即将用到。方法一:sent in a header
headers = {'User-Agent':'Mozilla/5.0', 'Authorization': 'token ef802a122df2e4d29d9b1b868a6fefb14f22b272', 'Content-Type':'application/json', 'Accept':'application/json' }
方法二:sent as a parameter
https://api.github.com/?access_token=OAUTH-TOKEN
-
如何实现对结果分页?
Github一页的上限是100条item,在后面加上page=1&per_page=100即可,建议加上升序或降序排列,后续处理数据将更加方便,根据star值降序排列采用的是:https://api.github.com/search/repositories?q={search}&page=4&per_page=100&sort=stars&order=desc
-
如何爬取一千个以上的仓库地址?
Github规定一次搜索最多只能展示1000条信息,所以当需要爬取两千条或更多时,我们采用分批次的爬取,而将他们连起来的是stars
参数,即开源仓库被点赞的次数。当爬取到第一千个仓库时,记录它的stars
值x
,再重新建立请求,爬取stars<=x
的仓库,如此便可获取一千条以上的仓库地址。
最终成功爬取数据的代码如下:
import time
from urllib.request import urlopen
from urllib.request import Request
import json
def get_results(search, headers, page, stars):
url = 'https://api.github.com/search/repositories?q={search}%20stars:<={stars}&page={num}&per_page=100&sort=stars' \
'&order=desc'.format(search=search, num=page, stars=stars)
req = Request(url, headers=headers)
response = urlopen(req).read()
result = json.loads(response.decode())
return result
if __name__ == '__main__':
# Specify JavaScript Repository
search = 'language:javascript'
# Modify the GitHub token value
headers = {'User-Agent': 'Mozilla/5.0',
'Authorization': 'token c90aec95de21a5ee46ee3e1e8f728f50a4ccc2c4',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
count = 1
# The highest value of JavaScript repository STAR is 321701, repository is freeCodeCamp.
stars = 421701
for i in range(0, 2):
repos_list = []
stars_list = []
for page in range(1, 11):
results = get_results(search, headers, page, stars)
for item in results['items']:
repos_list.append([count, item["name"], item["clone_url"]])
stars_list.append(item["stargazers_count"])
count += 1
print(len(repos_list))
stars = stars_list[-1]
print(stars)
with open("./top2000Repos.txt", "a", encoding="utf-8") as f:
for i in range(len(repos_list)):
f.write(str(repos_list[i][0]) + "," + repos_list[i][1] + "," + repos_list[i][2] + "\n")
# For authenticated requests, 30 requests per minute
# For unauthenticated requests, the rate limit allows you to make up to 10 requests per minute.
time.sleep(60)