一百行js,實現極簡知乎答題王輔助

MarsDes發表於2018-01-30

前言

最近答題類的遊戲各種火,辦公室玩的人也不少,還上各種的輔助。上網找了一遍,大多是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!!!

相關文章