跨平台脚本开发技术实验报告 github cache

2021-2022学年第2学期

实 验 报 告

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tKYnUdkJ-1665463185652)(zucc.png “ZUCC”)]

  • 课程名称:跨平台脚本开发技术
  • 实验项目: 期末大作业
  • 专业班级__
  • 学生学号_
  • 学生姓名__
  • 实验指导教师

代码 后端 egg js

实验内容

  1. 最终报告 以上部分自己删除

  2. 项目分工表格

    • 1人项目权重为1.0
    • 2人项目权重和为 1.9
  3. 项目自我评估表

    frp使用教程(转) - 简书 (jianshu.com)

    响应式编程(Reactive Programming)介绍 - 知乎 (zhihu.com)

    FRP(函数时 反应式编程,不是公网穿透啊,那没事了
    

    没有内网穿透,放在阿里云上了,直接公网

    给 MQTTX项目提了一个issue,虽然没写代码,而且和我的项目没啥关系,但是他是个ts项目,也是electron跨平台的,而且我觉得我的这个issue是关于数据量大的时候性能改进的,虽然我没写代码,但是我觉得我想法还可以,也去看了源码,不知道能不能在老师这加点印象分😀

    When the data volume exceeds 7000, mqttx will become abnormally stuck · Issue #914 · emqx/MQTTX (github.com)

    响应式编程 ,on 什么的应该就是响应式吧,http库的使用

       http.get(wz, function (res) {
                res.on("data", function (chunk) {
                    strHtml += chunk;
                })
                res.on("end", function () {
                    var $ = cheerio.load(strHtml);
    

    函数式 cheerio爬虫,函数当参数,函数连续点,应该就是函数式了

    let title = $(" h2 > a",titleDiv).text()
    
    技术点自评等级:(1-5)备注
    FRP(函数式 反应式编程1没有吧
    session Storage1无状态没有session
    响应式编程3http库的使用
    函数式编程3cheerio爬虫
    xx 框架5egg.js
    ORM 工具4egg.js 的mysql
    Graph QL1这好像是前端直接sql,我没有
    cheerio爬虫5
    后台轮询5
    got reqPromise https http 请求4调试了多种请求库
    pm2部署服务器4
    防抖3
    上传图片 fs 文件操作、删除等4
    超时函数3
  4. 项目说明

    1. 项目 是基于现有的egg-demon代码

      starplatinum111/egg-demon (gitee.com)

      他的项目作为demo,egg的框架有了,但是业务逻辑都是我自己写的

      可见项目文档

      https://acc15t4bm5.feishu.cn/docs/doccnLnginRRAuyalHbuiCevYhf

      运行视频 https://www.bilibili.com/video/bv1zr4y1q7NC

      http://starplatinumora.top:8086/ 在线预览

      图片 https://acc15t4bm5.feishu.cn/docs/doccnzg9HsaG6pP0QQEmDrRxuug

      可以是手机版本的,界面是按照手机版的界面分辨率做css的

      一开始是我自己想做的一个小工具,因为GitHub访问慢嘛,我就希望把他的数据cache下来,放在自己服务器,不就快了嘛,想法很简单,但是我觉得效果不错。当时我先拿SpringBoot写的,后来听说这节课要拿NodeJs写后端,我看刚好合适,就改技术栈,用egg.js 写后端,拿来当作大作业了

      github本身不稳定,有时候加载10s都是有的,挺常见的,但是我这个用的github API,首先他不请求前端,已经快了,然后我再缓存自己服务器,那更快了,不用去访问国外服务器了。issues我本身是不缓存的,直接github API拿,也挺快的,一页一秒钟应该是可以出来的

      因为github慢很多的原因是前端的资源,js,css啊啥的,是从各种cdn里拿来的,但是有些被墙了,所以很慢,然而github本身没有被墙,所以他的后端api还是挺快的。然后还有个特点,github仓库的仓库名和描述是不容易改的,所以他的数据缓存也问题不大,他的一致性要求不高,所以哪怕一个礼拜删一次缓存,那也没关系,不像秒杀啊啥的,需要高一致性,毕竟是钱,搞错了一个订单都不行。

      还有就是api不设防,直接跨域,所以直接axios请求就行,不像知乎,参数都是加密的,没办法请求,毕竟他的内容都是可以用来赚钱的,数据为王,本来就是商业性的,这挺正常的。如果能解决这个加密问题,我觉得别说毕设了,拿个博士论文应该问题不大吧。那这个api开源的好处就是可以很简单的使用,我做起来也方便。所以我觉得这个题目很适合我来做课设。

      公司规定所有接口都用 post 请求,这是为什么? - 知乎 (zhihu.com)

  5. 解决技术要点说明

    • 解决 服务器部署问题 问题, 关键代码与步骤如下
    • egg.js 打包后台 部署 https://blog.csdn.net/qq_35241223/article/details/97306900

      cnpm install pkg -g

      本来想要pkg 打包为 可执行文件 ,部署到服务器上的,但是踩了很多坑。后来发现这种想法是不对的,js的服务应该直接源代码扔到服务器上,cnpm install,然后拿pm2跑服务

      过程错误可见

      https://acc15t4bm5.feishu.cn/docs/doccn0a4VbMf2GDg0JE5kLLErxc

      打包失败

      https://acc15t4bm5.feishu.cn/docs/doccnE5zeKRbx0Y9i3ReMcukyfb

    • 解决问题 cheerio不知道怎么在某个节点之下去找节点, 关键代码与步骤如下
    • https://acc15t4bm5.feishu.cn/docs/doccnFp7PwLdygo0fUnykeedicd

    • cheerio 在一个元素基础上查询

      请问我在查询到一个元素之后,再在这个元素的基础上查询应该怎么做呢。比如在java里用 jsoup 是这样实现的。搜索了repoLis,然后遍历这个lis ,每个元素里面再通过elementLi.select查找

      Elements repoLis= newDoc.select("#js-pjax-container > div > div.col-12.col-md-9.float-left.px-2.pt-3.pt-md-0.codesearch-results > div > ul > li");
      List<GitPageRepo>list=new ArrayList<>();
      for (Element elementLi : repoLis) {
         Elements repo1Dom = elementLi.select("div.mt-n1.flex-auto");
      

      但是在cheerio 里面就不知道怎么弄了,也没有代码提示。。

      感觉这样也不对。。

        let repoLis = $("#js-pjax-container > div > div.col-12.col-md-9.float-left.px-2.pt-3.pt-md-0.codesearch-results > div > ul > li");
      
          repoLis.each((idx, item) => {
      
              let repo1Dom = $(item).$("div.mt-n1.flex-auto")
      
              console.log(repo1Dom.text());
          })
      

      我知道了 这样应该可行 let title = $(" h2 > a",titleDiv).text(), 第二个参数是从这个root开始找

         getBaidu:function(query, page) {
        
              const wz = "http://cn.bing.com/search?q=%E7%99%BE%E5%BA%A6&cvid=26d0fce0bc27499b9eabc8bec30cc1b9&aqs=edge..69i57j0l4j69i61l3j69i65.894j0j1&pglt=43&FORM=ANNTA1&PC=U531"; //网址
      
              var strHtml = "";
              var results = [];
              http.get(wz, function (res) {
                  res.on("data", function (chunk) {
                      strHtml += chunk;
                  })
                  res.on("end", function () {
                      var $ = cheerio.load(strHtml);
                
                      let titleDiv = $("#b_results > li:nth-child(1) > div.b_title");
                      let title = $(" h2 > a",titleDiv).text()
                      // 这样应该是可行的
                      console.log("title");
                      console.log(title);
                 
                  });
              })
      
          },
      

因为js类型系统还是差了点,不像java代码即是文档,js的api文档查不到就很难写,当时花了很多时间去查资料,还有自己试代码

因为 rp 是没有timeout参数的,或者说我文档里没找到,然后就找了个超时用的函数,这个我觉得挺通用的,挺好

因为是两个promise 竞赛,所以要用 const rp = require(‘request-promise’); 这个库,返回的是promise

function waitWithTimeout(promise, timeout, timeoutMessage = 'timeout') {
  let timer;
  const timeoutPromise = new Promise((_, reject) => {
    timer = setTimeout(() => reject(timeoutMessage), timeout);
  });
  // race 他俩比赛,谁先成功就干啥 ,因为timeoutPromise 设置了超时之后返回超时的信息
  // 所以外面接到他超时的字符串就是超时啦,虽然说也不是很优雅吧,因为万一不超时的时候也返回这个字符串呢,
  // 但是这种情况很少见 , 或者说只要只要你把timeoutMessage写成一个很乱的,不可能是正常返回的东西,那他就是准确的
  return Promise.race([ timeoutPromise, promise ])
    .finally(() => clearTimeout(timer)); // 别忘了清 timer
}

github 是https的,所以http不能请求,需要用https

const http = require(‘http’);

const https = require(‘https’);

cheerio最后不能是空格

 const topics = $('  div:nth-child(3) > div:nth-child(1) > a', repo1Dom);
 正确
 const topics = $('  div:nth-child(3) > div:nth-child(1) > a ', repo1Dom);
 错误
函数式 list.each
    repoLis.each((idx, item) => {
   
      const repo1Dom = $('div.mt-n1.flex-auto', item);

利用浏览器 方便的获取 xpath路径

爬虫获取路径_哔哩哔哩_bilibili

写了一个mysql save函数,JPA用多了, save还是爽的,搜出来了就更新,搜不出来就插入

const MySqlUtil = {
  async save(mysql, tableName, obj) {
    const firstById = await mysql.get(tableName, {
      id: obj.id,
    });
    if (firstById === null) {
      return await mysql.insert(tableName, obj);
    }
    return await mysql.update(tableName, obj);

  },
};

一个典型的 axios请求Global.axiosUrl 写在一个类里,其他地方都是调用他,这样改api位置了只要改一处,codeError 也是Global里定义

 axios
        .post(Global.axiosUrl + "issue/issues", data, jsonDic)
        .then((response) => {
          if (response.data.port === codeError) {
            // this.$message.error('账号或者密码有误');
            ElMessage.success("账号或者密码有误");
          } else {
            this.tableData = response.data.data;
            console.log("this.tableData");
            console.log(this.tableData);
          }
        })
        .catch(function (error) {
          console.log(error);
        });

因为点击获取issues 万一点击了很多次呢,万一一秒钟点击10次,请求太多,不好的,所以要防抖,隔了几秒才能发请求

  getIssues() {
      if (this.canHit) {
        this.getIssuesDo();
        // 防抖
        this.canHit = false;
        var auth_timetimer = setInterval(() => {
          // this.timer--;
          this.canHit = true;
          clearInterval(auth_timetimer);
        }, 1000);
      }

上传图片

https://acc15t4bm5.feishu.cn/docs/doccnWpEyPaLRAMcRzpTQNVcTyc

数据库字符集

https://acc15t4bm5.feishu.cn/docs/doccnHsCJTYHWkeOBbIepRLQ00e

pm2 log 打印

https://acc15t4bm5.feishu.cn/docs/doccnAJoVJG3F5vpSaFXiJtYZnG

nodejs 报错

https://acc15t4bm5.feishu.cn/docs/doccnAfMDDr0TIpTcBWL1UKBY5c

delete

let  id=ctx.params.id

  axios.delete(`${Global.axiosUrl}img/delete/${img.id}`, {id:img.id}).then((res) => {
        console.log("res");
         console.log(res);
      });
  
  w
  fs.unlink(target,function(error){
  if(error){
      console.log(error);
      return false;
  }
  console.log('删除文件成功');
})
  1. 心得体会(结合自己情况具体说明)

    • 大项目开发过程心得

      • 遇到哪些困难,经历哪里过程,有哪些收获
      • cnpm i egg-bus --save

        cnpm install --save request-promise

        因为库没有 的话 貌似是要重新 run dev的 ,当你启动了这个项目之后,cnpm i 了新的东西,应该是没办法使用的,需要重新run dev,新的库才会被编译

      • egg 报错不是很好,mysql ip 密码之类写错了,启动会失败,但是他的报错不明确

      • yarn 各种bug 目前觉得bug最少的还是cnpm,虽然有时候也会有bug吧

      • https://acc15t4bm5.feishu.cn/docs/doccnyPetglOT7BjKWiRAKsT0eh

      爬虫想扔到消息队列里去的,但是egg-bus没有调通。因为关键词查询仓库的接口github好像是没有给的,只能get他的html然后爬虫他的网页数据,但是这意味着他的前端也要拿到了,所以失败率非常高,基本5次能抓取到一次就很好了,而且很慢,所以要异步的放到队列里去做。

      https://acc15t4bm5.feishu.cn/docs/doccniNDEZ5CRu2swLEPxoaEPLf

      我是写了个"线程"去让他反复做耗时操作,虽然js没有线程 但是我给他这样取名了

      class WhileReqThread {

      因为他是异步的,用起来跟java的线程很像,这样理解是很方便的

      每秒去尝试执行一次,如果次数超过5次,就不做了

        if (that.times < that.tryTimes) {
              // reject("error times out")
              return;
            }
            setTimeout(() => {
              that.tryTimes++;
              that.reqTry(urlStr);
            }, 1000);
      
      
    • 本课程建议

      • 课程难度方面,
      • 计算的本质太难了,calcuslas 、lambda表达式都很难,虽然挺有意思的,但是要理解一个东西都需要很长时间,而且面试也不会考,找工作没用,所以不是很希望花时间在这里,比较适合计算机科学家去研究,而不是应用型大学来学,希望能让有钱人去学这个东西,因为先富带动后富,就是让有钱人,对于生活无忧的人,去研究科学,去发展生产力,去提高国家实力,然后不要和穷人、打工仔来卷前后端,这样穷人有工作,能过活,有钱人可以发展国家,多好啊。而不是有钱人、读书好的人,去卷考公,当了公务员也不知道在干嘛

      • 进度方面,

      • 挺合理的

      • 课程内容,

      • 有意思 但是难,画的时间多,不适合应用型大学,找工作计算的本质应该不太有用,应该卷面经,vue的diff算法,js的Promise啥的,其实也是学了吧,其实还是有点像面经的,

      • 怎么说呢,以后找个955的工作空闲时间学学计算的本质、编译器啥的,还挺有意思,996就算了,没时间学,现在上学期间忙着找工作,也没时间学

      • 授课方式等,
      • 资源很好 很多,放在网站上自己看,很舒服。其实我希望今年讲过的课,有学在城院的视频,可以直接给下届的同学看就行了,可以快进,返回去看,反复看,多好啊,上课可以让同学来问问题,上课可以不讲课了,可以去github上逛,搜集更多的好的资料给同学,不是更好吗

      • 不知道老师有没有兴趣看看我对好的课程的定义

      • 什么样的老师是好老师?应该怎么样做一个好老师? - 求你别让我写论文的回答 - 知乎 https://www.zhihu.com/question/25026687/answer/2344876775

空闲时间学学计算的本质、编译器啥的,还挺有意思,996就算了,没时间学,现在上学期间忙着找工作,也没时间学

授课方式等,

资源很好 很多,放在网站上自己看,很舒服。其实我希望今年讲过的课,有学在城院的视频,可以直接给下届的同学看就行了,可以快进,返回去看,反复看,多好啊,上课可以让同学来问问题,上课可以不讲课了,可以去github上逛,搜集更多的好的资料给同学,不是更好吗

不知道老师有没有兴趣看看我对好的课程的定义

什么样的老师是好老师?应该怎么样做一个好老师? - 求你别让我写论文的回答 - 知乎 https://www.zhihu.com/question/25026687/answer/2344876775

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值