机核网页端机组插件

Tampermonkey,确实是可以做一些很轻量但是很实用的小工具,总体上四五百行代码,以机核对外暴露的动态查看接口为基础,对机组消息进行遍历查询,然后二次拼装成单独页面进行展示.

核心代码

逻辑其实并不复杂,无非是数据的获取和拼接而已,加一点样式重写,加一点异步请求,加一点二分查找,就成了…

机核的机组是以顺序id进行存储的,但是删除的机博会存在ID占用了,但是数据为空,所以定向查询时我会做一点冗余,比如向后顺序遍历5个ID能返回3条数据就算成功.

另外评论的接口也从机核主站中扒出来了,也能成功做了个简单的评论显示.

唯一美中不足的就是.heic类型的苹果动态图片没法直接在H5中做展示,我也没再做转化,本身就是一个几百行的小脚本,引一堆JS做图片类型转换太蠢了.

锚点更新模块

三方插件怎么能获取到机核那边最新机博的ID以做加载锚点呢?

其实也简单,搞个定时脚本然后每小时做次更新,然后暴露给脚本就可以了.

手头没服务器的我调研一圈后最后敲定了 github-actions 的解决方案.

定时脚本,整点执行后写入到git库指定文件中,然后油猴脚本启动时拿固定路径内的ID值就可以了.

为了减少频繁请求,查询时候做了个伪二分算法,以增量数组的方式写了个小算法.

一切都很合理,唯一不好的地方就是每天固定会有十几条的更新污染git库commit记录.

源码

//锚点更新脚本
const fs = require(‘fs’)
const https = require(‘https’);
const cheerio = require(‘cheerio’);


const Gtalk = ‘https://www.gcores.com/talks/‘
const GitUrl = ‘https://github.com/TOKdawn/gcores-talks-Viewer/blob/main/crawler/TID.html’
const intervalList = [100, 50, 25, 10, 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] //加值率区间
var OLD_ID = ‘’
const add = function (a, b) {
  return a + b
}


function setHTML(TID) {
  if (!TID) {
    console.log(“TID is null”)
    return
  }
  fs.writeFile(‘./crawler/TID.html’, parseInt(TID, 10).toString(), err => {
    if (err) {
      throw err
    } else {
      console.log("TID.html success")
      // console.log(htmlStr)
    }
  })
}

function getTID() {
  return new Promise((resolve) => {
    console.log('开始获取TID')
    https.get(GitUrl, res => {
      let html = ''
      res.on('data', data => {
        html += data
      })
      res.on('end', () => {
        console.log('GIT请求成功')
        let $ = cheerio.load(html);
        let id = $('.blob-code-inner').text();
        if (id) {
          resolve(id)
        } else {
          console.log('HTML解析错误')
          resolve(null)
        }
      })
    })
  })
}

Function tryTID(TID) { //检测TID要同时连续监测三个,因为存在一些删除的机博,占用了TID但是页面拿取为空
  let promiseList = []
  for (let I = 0; I < 3; I++) {
    promiseList[I] = new Promise(resolve => {
      let url = Gtalk + (TID + i)
      https.get(url, res => {
        let html = ‘’
        res.on(‘data’, data => {
          html += data
        })
        res.on(‘end’, () => {
          let $ = cheerio.load(html);
          let DOM = $(‘.aat_container’).children().length;
          console.log(‘DOM’, DOM)
          if (DOM) {
            resolve(1)
          } else {
            resolve(0)
          }
        })
      })
    })
  }
  return promiseList
}

async function run() {
  OLD_ID = await getTID()
  OLD_ID -= 0
  console.log('获取TID成功:', OLD_ID)
  let searchFlag = true;
  let addNum = 0; //初始增值
  let INI = 0; //增值刻度
  let tryFlag = true; // 检测标识
  while (searchFlag) {
    addNum += intervalList[INI];
    await Promise.all(tryTID(OLD_ID + addNum)).then(res => {
      if (res.reduce(add) >= 1) { //三个中有一个有效就成功
        console.log(‘检测成功:’, res, OLD_ID + addNum)
        tryFlag = true
      } else {
        console.log(‘检测失败:’, OLD_ID + addNum)
        tryFlag = false
      }
    })
    if (!tryFlag) { //如果超越边界
      addNum -= intervalList[INI]; //还原成上次增值
      INI++; //维度减小
    }
    if (!tryFlag && INI >= 9) { //结束条件
      searchFlag = false
    }
  }
  console.log(‘最终结果’, OLD_ID + addNum);
  setHTML(OLD_ID + addNum)
  console.log(‘结束 结束’)
}

run();

最后更新于