我正在尝试访问Github上所有拥有超过5000颗星的存储库。我编写了这个抓取工具来与 Node 一起使用.js(它在 Cloud9 环境中运行(:
var request = require('request');
var fs = require('fs');
var options = {
url: 'https://api.github.com/repositories',
headers: {
'User-Agent': 'myusernamehere'
},
qs: {
stargazers: 5000
}
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(response.headers);
fs.writeFile('output_teste.json', body, function (err) {
if (err) throw err;
console.log('It's saved!');
console.log(response.statusCode);
});
} else {
console.log(response.statusCode);
}
}
request(options, callback);
但结果不是所有的存储库,只是所有存储库的第一页。如何在请求模块中使用分页?我试图在文档中找到示例,但它们并不那么清楚。还是我需要使用其他库或另一种语言执行此操作?
谢谢!
您应该修改查询字符串以包含"since"的值。您可以在 github 文档中阅读更多内容。https://developer.github.com/v3/repos/#list-all-public-repositories
查询字符串为 自
https://api.github.com/repositories?since=364
GitHub API 时收到的response.headers.link
中提供的分页数据来了解是否还有更多页面可供调用。
一种方法是遍历页面,直到没有更多的新页面,此时您可以写入文件并从函数返回。
在每个循环中,您可以使用concat
(我假设响应正文作为数组传递(,然后将数据传递给下一个函数调用,从而添加到已有的数据中。
我重写了您的代码以包含这种技术的基本实现:
var request = require('request');
var fs = require('fs');
var requestOptions = function(page) {
var url = 'https://api.github.com/repositories?page=' + page;
return {
url: url,
headers: {
'User-Agent': 'myusernamehere'
},
qs: {
stargazers: 5000
}
};
};
function doRequest(page, incomingRepos) {
request(requestOptions(page), function(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(response.headers);
var currentPageRepos = JSON.parse(body);
var joinedRepos = incomingRepos.concat(currentPageRepos);
var linkData = response.headers.link;
// if response does not include reference to next page
// then we have reached the last page and can save content and return
if (!(linkData.includes('rel="next"'))) {
fs.writeFile('output_teste.json', JSON.stringify(joinedRepos), function(err) {
if (err) throw err;
console.log('It's saved!');
});
return;
}
page++;
doRequest(page, joinedRepos);
} else {
console.log(response.statusCode);
}
});
}
doRequest(1, []);