一百行js,实现极简知乎答题王辅助

7,246 阅读3分钟

前言

最近答题类的游戏各种火,办公室玩的人也不少,还上各种的辅助。上网找了一遍,大多是Python,php写的,寻思自己基于node也写个试试。

王者镇楼

知识点

就一点:js 嗯,so easy

思路

v1.0 获取题目 -> 百度一下^_^ -> 返回处理过的答案 -> 选一个

获取题目

AnyProxy 说明文档通读一遍就能用,这里我是作为npm模块使用。
小程序接口都是https的,需要安装证书。*部分手机安装证书需要在系统安全以及网络连接高级设置里面安装
一波操作过后,打开localhost:8002看到下图,恭喜你,成功了一点点。

监听接口成功
虽然我英语不好但还是一眼就发现了找题目这个接口/question/bat/findQuiz

//把这个接口数据打印出来看下
 *beforeSendResponse(requestDetail, responseDetail) {
    if(requestDetail.url.indexOf('https://question-zh.hortor.net/question/bat/find')==0){
      let body = JSON.parse(responseDetail.response.body.toString())
      console.log(body)
      return responseDetail;
    }
  },

题目接口返回
一看quiz就是题干,options就是选项。

百度一下

*你要搜狗谷歌必应来一下也可以
爬搜索结果这里用的是node-https模块 为什么不直接用https.get,控制台会出现友好提示noscript的,try it
当然用一些封装好的模块也行,甚至puppeteer也行。不过这要安装几十m的chromium还不一定成功,少梯子的话。
不过我们是以学习为主的嘛,能自己动手就自己动动。
浏览器随便百度一下,https://www.baidu.com/s?ie=UTF-8&wd=mars,一个简单的搜索链接大概这样,mars就是搜索关键词,打开控制台,看下请求头的数据。

request的option

//那么我们百度的request的option就大概如下
let reqOptions = {
    hostname: 'www.baidu.com',
    method: 'GET',
    headers: 
        { 
            Connection: 'keep-alive',
            'User-Agent': 'Mozilla/5.0等等等',
            'Accept-Encoding': 'gzip, deflate, br',
            Cookie: '一段很长的东西'
        },
    };

为了下一步用async/await,封装一个sendReq方法。这里还需要对Buffer简单了解下,请求结果是Buffer数据需要处理下

function sendReq(reqOptions,quiz){
  const path = `/s?wd=${encodeURI(quiz)}` //题干需要encode一下
  reqOptions = {...reqOptions,path}
  return new Promise(resolve=>{
    callback = (res) => {
      let bufferList=[];
      res.on('data',(d)=>{
          bufferList.push(d)
      });
      res.on('end',()=>{
        let buffer = Buffer.concat(bufferList);
        zlib.gunzip(buffer, (err, decoded)=> {
          resolve(decoded.toString());
          console.log(decoded.toString())
        })
      });
    }
    let req = https.request(reqOptions,callback);
    req.end();
  })
}

跑下sendReq(reqOptions,mars)看到下面的东西,恭喜你又成功了一点。

百度一下结果

处理结果

把第一步拿到的quzi放到第二部的sendReq里面用cheerio处理下。通俗点就是拿到题目然后去百度一下,然后统计下题目个选项在搜索的结果出现的次数。

...
let content = yield sendReq(reqOptions,body.data.quiz)
const $ = cheerio.load(content, { decodeEntities: false });
const resList = $('.result');
options.forEach((answer,i) => {
    let time = 0;
    resList.each((index, result)=>{
      if($(result).text().indexOf(answer)>=0){
        time++
      }
    })
    options[i] = `${answer}[${time}]`
});
body.data.options = options
body=new Buffer(JSON.stringify(body))   //还原数据类型
responseDetail.response.body = body
return responseDetail;
...

最终结果

最终结果
一般选最多的,不过百度也有不知道的时候,至于否定类的题目需要你人工智能处理下选最少,这里不做进一步处理

总结

至此这个简单的辅助就算完成。
你会发现这个东西还有很多可以完善的地方

  • 并发搜索,百度一下不行,谷歌搜索必应一起来再统计结果
  • 自动提交答案,上图接口2就是提交答案的接口,我们可以再拿到结果之后直接发起答题请求,满分不要太简单了。
  • 本地题库,建立本地题库,拿到题目后先查本地题库,有记录直接答题,无记录再搜索引擎。
  • 等等

其他答题类的辅助基本都可以按这思路实现
作为答题应用也可以从上面的环节做更多的处理,防止辅助的出现。 ps 最近好像要出现金赛,反正我是不敢玩。说不定对面是阿尔法狗 ps 被封之后数据转移到知乎答题王了,好久没关注了,最近有github提问就更新下,就改个题目接口地址https://question变成https://question-zh 项目地址
欢迎star!!!欢迎star!!!欢迎star!!!