热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Vercel托管Next实现GitHubTrendingAPI

Vercel托管Next实现GitHubTrendingAPI-想写一个GitHub的拓展小程序,GiHubTrending必不可少。可GitHub未提供Trending的API,

想写一个 GitHub 的拓展小程序,GiHub Trending 必不可少。可 GitHub 未提供 Trending 的 API,只能自己爬了。

方案一:小程序 wx.request 请求网页得到 HTML 字符串后解析;

方案二:使用云函数请求网页得到 HTML 字符串后解析;

我选择了方案二

噼里啪啦写完了,上线。然后发现云函数访问不了外网,无法使用手机的代理服务,GitHub 在国内也很不稳定,所以经常会请求挂掉。

无意间发现 Vercel 在国内的访问速度不错,又能免费托管云函数,就想到通过 Vercel 代理请求 GitHub Trending,想到就干,弄完效果还不错,不会挂了。

登录/注册 Vercel

新建 Next.js 项目

新建 Next 项目,未接触过 Next 和 Vercel 的同学可以使用 Vercel 提供的 Next.js 模版。Vercel 项目需要仓库托管,可一键克隆模版项目到 GitHub。

编写 API

主要思路是请求网页 HTML 字符串使用 cheerio 解析。

在项目 api/ 文件夹下新建 trending.jsapi/ 文件夹内文件都会自动转为 Node.js 服务,参考 API Routes),编写请求方法。如何解析我就不赘述了,访问网页打开调试自己找规律就好,直接上代码

import fetch from 'node-fetch';
import cheerio from 'cheerio';

const fetchTrendingList = async () => {
  const url = 'https://github.com/trending';
  const text = await fetch(url).then((data) => data.text());
  const $ = cheerio.load(text);
  const list = $('.Box .Box-row')
    .get()
    .map(repo => {
      const $repo = $(repo);
      const title = $repo.find('.h3').text().trim();
      const [owner, name] = title.split('/').map(v => v.trim());
      const description = $(($repo.children())[2]).text().trim();
      const language = $repo.find('[itemprop="programmingLanguage"]').text().trim();
      const starCount = $repo.find('[aria-label="star"].octicon.octicon-star').parent().text().trim();
      return {
        owner: {
          login: owner,
          avatar_url: `https://github.com/${owner}.png`
        },
        name,
        description,
        language,
        stargazers_count: starCount
      };
    });
}

export default async (req, res) => {
  const resp = await fetchTrendingList();
  res.status(200).json(resp);
}

上传到 Git 仓库后触发 Vercel 构建部署,现在访问 https://.vercel.app/trending 即可得到 JSON 返回。

以上不支持筛选参数,接下来增加几行代码是 API 和 GitHub Trending 保持一致。

/**
 * 增加参数支持,参数均为可选
 *
 * @param {object} params
 * @param {string} [params.language] Language
 * @param {'daily'|'weekly'|'monthly'} [params.since] Date range
 * @param {string} [params.spoken_language_code] Spoken Language
 */
const fetchTrendingList = async (params) => {
  let url = 'https://github.com/trending';
  // 结构出路径参数
  const { language, ...query } = params;
  if (language) {
    url += `/${language}`
  }
  // 组合 query 字符串
  const queryString = Object.keys(query).map((key) => `${key}=${query[key]}`).join('&');
  if (queryString) {
    url += `?${queryString}`;
  }
  
  const text = await fetch(url).then((data) => data.text());
  // ... 后面的无需改动
}

export default async (req, res) => {
  // 传递 req.query
  const resp = await fetchTrendingList(req.query);
  res.status(200).json(resp);
}

现在 API 支持了筛选参数,但还没结束。当你访问 https://.vercel.app/api/trending/Javascript 时会报 404。因为该路由文件不存在。

一种方案是使用 Next 的动态路由 api/trending/[language].js,但是这样并不会匹配 api/trending,官方方案是创建两个路由文件 api/trending/index.jsapi/trending/[language].js。要么是相同的代码写两份,要么是写个公用方法引用。

我觉得麻烦,最终采用的 next.config.js 的 Rewrites 配置实现。项目没有 next.config.js 文件的新建。

module.exports = {
  async rewrites () {
    return [
      // :language 必须和 trending.js 里的请求参数 language 一致,language 会包含在 req.query 里
      { source: '/api/trending/:language', destination: '/api/trending' }
    ];
  }
}

到此为止是真的结束了,和 GitHub Trending API 一致。源码就不提供了,都在文章里。

GitHub扫码体验
weapp-mark

推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
author-avatar
尖塔顶的Cat
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有