最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • “Deno 在手,天下我有“,极速获取今日热榜

    正文概述 掘金(胡琦)   2020-12-02   448

    “Deno 在手,天下我有“,极速获取今日热榜

    源起

    “Deno 在手,天下我有“,极速获取今日热榜 本周,被@justjavac 巨佬的各个热搜榜项目吸睛了,抱着对技术的三分钟热情以及对优秀代码的学习心切,我又开始了新的代码拷贝旅程。二话不说,先git clone一顿操作猛如虎,定睛一看,好像这几个项目的实现都差不多,也请教了巨佬本尊确定实现是一样的,但为毛要开 4 个 repo 呢?也许这就是单一职责原则吧。然后,我寻思着能不能整合一下再加点别的热搜榜就能变成trending in one,是不是很棒的想法,哈哈哈哈。接下来,我还会对今日头条下手--”得热搜者得天下,热搜榜拿来吧!“,三下除二拿到了头条热搜榜(尽管需要输入图片验证码)。最后就是资源整合,不过发现 README.md 爆了,看来单例还是有单例的好。

    即刻获取今日热搜榜 ➡️ trending-in-one

    剖析

    关于如何实现热搜汇总,如果不看源码,我也只能想到调用相关热搜榜的接口来获取,可别人的接口又怎么会给你随意调用呢?通过拜读大佬的源码,我看到了通过正则匹配 DOM 节点获取对应的标题链接之类的,我看到了通过注释定位包裹的内容并进行替换,我看到了 JavaScript 如何处理重复的数据,我看到了如何借助 github action 实现 Deno 应用的构建……尽管只是一个微不足道的项目,却包罗万象,作者将各种技巧搭配自如、灵活运用,简直是出神入化、登峰造极啊(PS:在我看来事实如此)。

    “Deno 在手,天下我有“,极速获取今日热榜

    其实抛开语言和平台,要想实现热搜汇总榜,无非就是三步走:① 获取数据 ② 处理数据 ③ 输出数据。接下来从 Deno 的视角来详细解说这三步是如何走的:

    获取数据

    当我们遇到一个需求,可能要从它的本质出发,比如要实现热搜汇总,首先我们就需要各大平台的热搜数据,如今日头条热搜榜、知乎热门视频、知乎热门话题、知识热门搜索、微博热门搜索等等,怎么获取呢?常规的手段就是框按 F12 看看 Network,实在不行试试抓包工具.好在“前人栽树后人乘凉”,于是乎我们便有了各平台的接口,获取数据岂不是信手沾来。

    头条热榜:[https://is-lq.snssdk.com/api/suggest_words/?business_id=10016](https://is-lq.snssdk.com/api/suggest_words/?business_id=10016)
    
    微博热搜:[https://s.weibo.com/top/summary](https://s.weibo.com/top/summary)
    
    知乎热门话题:[https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=100](https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=100)
    
    知乎热门视频:[https://www.zhihu.com/api/v3/feed/topstory/hot-lists/zvideo?limit=100](https://www.zhihu.com/api/v3/feed/topstory/hot-lists/zvideo?limit=100)
    
    知乎热搜: [https://www.zhihu.com/api/v4/search/top_search](https://www.zhihu.com/api/v4/search/top_search)
    

    当然以上接口并非永久有效,目前来看也只能是能用多久用多久了,如果您不满足于此,亦可以试试推特、Medium 等等(PS:好人一生平安)。不过,上边的接口中,微博热搜特立独行,她返回的是 HTML 需要用到正则匹配即可拿到热搜标题和链接,正则可把我难住了:/<a href="(\/weibo\?q=[^"]+)".*?>(.+)<\/a>/g,似懂非懂。各位少侠可否移步评论区多多指教?

    “Deno 在手,天下我有“,极速获取今日热榜

    以今日头条为例,获取数据似乎显示特别简单,但扪心自问 await、fetch、TypeScript 我又了解多少呢?

    const response = await fetch(
      "https://is-lq.snssdk.com/api/suggest_words/?business_id=10016",
    );
    
    if (!response.ok) {
      console.error(response.statusText);
      Deno.exit(-1);
    }
    
    const result: ToutiaoTopSearch = await response.json();
    const words = result.data[0].words;
    

    处理数据

    最终我们的数据可能是这样的--参见2020-12-01 头条热搜

    “Deno 在手,天下我有“,极速获取今日热榜

    细心的小伙伴也许看到了.md 文件中的注释,就是这注释起到了关键的作用,移花接木?为他人做嫁衣?在进行数据更新的时候,我们可以巧妙地利用注释作为参照,动态替换注释开头和注释结尾中间的内容,利用 Deno 标准库及一些内置 API 完成文件操作,比如今日头条热搜数据的创建及更新:

    export function createTuotiaoList(words: ToutiaoWord[]): string {
      return `<!-- BEGIN TOUTIAO -->
    <!-- 最后更新时间 ${Date()} -->
    ${
        words.map((x) => `1. [${x.word}](${x.url})`)
          .join("\n")
      }
    <!-- END TOUTIAO -->`;
    }
    
    export async function createReadme4Toutiao(
      words: ToutiaoWord[],
    ): Promise<string> {
      const readme = await Deno.readTextFile("./README.md");
      return readme.replace(
        /<!-- BEGIN TOUTIAO -->[\W\w]*<!-- END TOUTIAO -->/,
        createTuotiaoList(words),
      );
    }
    
    

    另外再对比新旧数据的时候,用到了常用的数组迭代方法及**Object.entries()** ,感觉 MDN 还得多刷,完全不熟练,尤其是串起来的时候:

    /** 合并两次热搜并去重 */
    export function mergeWords4Toutiao(
      words: ToutiaoWord[],
      another: ToutiaoWord[],
    ): ToutiaoWord[] {
      const obj: Record<string, string> = {};
      for (const w of words.concat(another)) {
        obj[w.url] = w.word;
      }
      return Object.entries(obj).map(([url, word]) => ({
        url,
        word,
      }));
    }
    

    输出数据

    其实在处理数据的时候,我们基本完成了数据输出的准备工作,鉴于本项目中只输出为.md 文件和.json 文件,直接调用之前的处理数据方法即可,简单粗暴:

    export async function toutiaoSearch() {
      // 保存原始数据
      await Deno.writeTextFile(fullPath, JSON.stringify(wordsAll));
    
      // 更新 README.md
      const readme = await createReadme4Toutiao(wordsAll);
      await Deno.writeTextFile("./README.md", readme);
    
      // 更新 archives
      const archiveText = createArchive4Toutiao(wordsAll, yyyyMMdd);
      const archivePath = join("archives/toutiao-search", `${yyyyMMdd}.md`);
      await Deno.writeTextFile(archivePath, archiveText);
    }
    

    如果不局限于输出数据为文件,我们可以实现的功能就可以多了,发送热搜数据(或者任何您能获取到的数据)到邮件、短信、钉钉机器人……不禁又想起了老湿常说的“带薪拉屎”必备,想想每天早上第一泡就能享用热乎的热搜榜,似乎有种“家事国事天下事,事事关心”的错觉,坐着点开一条条热搜表示“朕已阅”……

    Github Action

    如果说 Serverless 是个好东西,那么Github Action怎么逃得过真香定律呢?在 GitHub Actions 的仓库中自动化、自定义和执行软件开发工作流程。您可以发现、创建和共享操作以执行您喜欢的任何作业(包括 CI/CD),并将操作合并到完全自定义的工作流程中。通俗点就是您可以为所欲为,比如定时构建 Deno 应用。为了能够每小时更新我们的热搜汇总,我们需要给 github 仓库新增**.github/workflows** 文件夹,也就是前边所说的工作流 ,然后新建 ci.yml 和 schedule.yml 告诉 Github Action 应该如何做,这样她就是听话的贴心小秘书了,因为她会告诉您每一次执行工作流的详细结果,就算构建失败也有邮件温馨提醒。至于 yml 的内容应该写啥,请参照官方文档和 Deno 社区经典案例(PS:好像是我的知识盲区,用得还不熟练,怕带坑)。 当然,如果想直接开干的话,可以在仓库的 Action 选项卡中获取到 github 提供的温馨建议。少年,亮剑吧! “Deno 在手,天下我有“,极速获取今日热榜

    尾声

    探索的脚步永不止步,不过于我,好像置身于小黑屋,无论我怎么走都无法走出去,十多年了,依旧原地踏步踏。小时候,梦想长大以后一家子各兄弟能大干一场实现家族企业的幻想却奈何爷辈早逝凝聚力尽失;到中学,怀恨于内心的脆弱被班主任拿捏死失去重点中学的入场券落为鸡头放弃自我;万幸有的大学读,却虚度光阴于网吧、操场、情人坡、后山,终费万事……到此刻及未来,终究要为过去的沉沦颓废而埋单。唉,年纪大了,还能怎么折腾?谨以此段,奉劝家中无矿、朝中无权的年轻人,莫虚度此生,至少 Deno 真香!

    完整项目地址: github.com/hu-qi/trend…


    起源地下载网 » “Deno 在手,天下我有“,极速获取今日热榜

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元