如何使用 Node.js 请求模块处理对 Github API 的多页请求



我正在尝试访问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, []);

最新更新