You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Node.js Request模块处理GitHub API多页请求以获取高星仓库?

处理GitHub API多页请求的解决方案

嘿,我来帮你搞定GitHub API的分页问题!首先得搞懂GitHub的分页逻辑:它默认每页返回30条结果,分页导航的链接会放在响应的Link HTTP头部里,我们要做的就是解析这个头部,递归请求每一页,直到没有“下一页”的链接为止。

核心思路:解析Link头部

GitHub返回的Link头部格式大概是这样的:

<https://api.github.com/repositories?stargazers=5000&page=2>; rel="next", <https://api.github.com/repositories?stargazers=5000&page=10>; rel="last"

这里的rel="next"就是下一页的URL,rel="last"是最后一页的URL。我们需要写个小函数把这些链接提取出来。

完整代码实现

我基于你现有的代码做了修改,添加了分页处理的逻辑,还加了速率限制的提示(避免被GitHub限流):

var request = require('request');
var fs = require('fs');

// 用来存储所有爬取到的仓库数据
let allRepositories = [];

// 解析Link头部的工具函数
function parseLinkHeader(linkHeader) {
  if (!linkHeader) return {};
  
  return linkHeader.split(',').reduce((links, link) => {
    const [urlPart, relPart] = link.trim().split(';');
    const url = urlPart.slice(1, -1); // 去掉前后的<>
    const rel = relPart.trim().split('=')[1].slice(1, -1); // 提取rel的值
    links[rel] = url;
    return links;
  }, {});
}

// 递归请求每一页的函数
function fetchPage(url) {
  const options = {
    url: url,
    headers: {
      'User-Agent': 'your-github-username' // 务必替换成你的GitHub用户名!
    },
    json: true // 自动把响应体解析成JSON,省得自己JSON.parse
  };

  request(options, (error, response, body) => {
    if (error) {
      console.error(`请求出错: ${error.message}`);
      return;
    }

    if (response.statusCode !== 200) {
      console.error(`API返回错误 ${response.statusCode}: ${JSON.stringify(body)}`);
      return;
    }

    // 把当前页的仓库数据合并到总列表里
    allRepositories = allRepositories.concat(body);
    console.log(`已获取第${response.headers['x-page']}页,累计收集${allRepositories.length}个仓库`);

    // 检查速率限制,避免不小心触发限流
    console.log(`剩余API请求次数: ${response.headers['x-ratelimit-remaining']}/${response.headers['x-ratelimit-limit']}`);

    // 解析Link头部,看看有没有下一页
    const links = parseLinkHeader(response.headers.link);
    if (links.next) {
      // 有下一页就继续请求
      fetchPage(links.next);
    } else {
      // 所有页都爬完了,写入文件
      fs.writeFile('high-star-repos.json', JSON.stringify(allRepositories, null, 2), (err) => {
        if (err) throw err;
        console.log('🎉 所有数据已保存到high-star-repos.json文件!');
      });
    }
  });
}

// 启动第一页的请求
fetchPage('https://api.github.com/repositories?stargazers=5000');

几个重要的注意事项

  • 必须设置User-Agent:GitHub API要求请求头里必须包含User-Agent(最好是你的GitHub用户名),否则会直接返回403禁止访问。
  • 速率限制:未认证的请求每小时只能调用60次API,如果你需要爬更多数据,建议添加认证——在请求头里加Authorization: token YOUR_GITHUB_TOKEN,这样速率限制会提升到每小时5000次(token可以在GitHub的设置里生成)。
  • 错误处理:代码里加了基本的错误处理,你可以根据需要扩展,比如添加重试逻辑(针对临时网络错误)。

内容的提问来源于stack exchange,提问作者Flavio Pessoa

火山引擎 最新活动