本来想通过抓取学小易的接口来进行查题,没想到抓取成功后,搜的第二道题,学小易就把我账号给封掉了。

抓包工具准备

  1. 一部已经root的手机
  2. 抓包软件httpCanary

    通过httpCanary抓取API

    登陆接口 :https://app.51xuexiaoyi.com/api/v1/login,会获取到api_token,查题需要。
    查题接口 :https://app.51xuexiaoyi.com/api/v1/searchQuestion

    运行环境

  3. node环境
  4. 下载依赖 npm i request request-promise-native -S
  5. 运行 node index.js

    程序代码

    配置文件config.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    const App = {
    'app-version':'1.0.6',
    platform:'android',
    device:'AkUmMFxRuen3SjFGi16BsRmFHoXUHa8Gq1KwDDlOSIw2',
    'user-agent':'okhttp/3.11.0'
    }
    module.exports = {
    login:{
    URI:'https://app.51xuexiaoyi.com/api/v1/login',
    headers:{
    device:App.device,
    platform:App.platform,
    'app-version':App['app-version'],
    'user-agent':App['user-agent'],
    'content-type':'application/json;charset=utf-8'
    }
    },
    searchQuestion:{
    URI:'https://app.51xuexiaoyi.com/api/v1/searchQuestion',
    headers:{
    device:App.device,
    platform:App.platform,
    'app-version':App['app-version'],
    'user-agent':App['user-agent'],
    'content-type':'application/json;charset=utf-8'
    }
    }

    }
    主要的查题程序searchQuestion.js
    登陆函数天自己的账号和密码即可。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    const Rp = require('request-promise-native')
    const Config = require('./config')
    const fs = require('fs')

    // 登陆
    function login(){
    const options = {method:'POST',uri:Config.login.URI,body:{'username':'XXXXXX','password':'XXXXXX'},headers:Config.login.headers,json: true}
    return Rp(options)
    }
    //搜题
    async function searchQuestion(question){
    let apiToken = JSON.parse(fs.readFileSync('./token.txt','utf-8'))
    const options = {method:'POST',uri:Config.searchQuestion.URI,body:{'keyword':question},headers:Config.searchQuestion.headers,json: true}
    options.headers.token = apiToken.api_token
    options.headers.t = String(Date.now())
    return Rp(options)
    }
    //保存token,不用每次都登陆请求
    async function saveToken(){
    let loginResult = await login()
    if(loginResult.code == 200){
    console.log(getTime() + '===>' +"token保存成功")
    fs.writeFileSync('./token.txt',JSON.stringify(loginResult.data),'utf-8')
    }else{
    console.log(getTime() + '===>' +"token保存失败")
    }
    }
    //定时更新 token
    async function updateToken(isRun,time){
    isRun && await saveToken()
    setInterval(async()=>{
    await saveToken()
    },time)
    }
    //当前时间
    function getTime(){
    const d = new Date()
    const y = d.getFullYear()
    const m = String(d.getMonth() + 1).padStart(2,'0')
    const da = String(d.getDate()).padStart(2,'0')
    const h = String(d.getHours()).padStart(2,'0')
    const f = String(d.getMinutes()).padStart(2,'0')
    const s = String(d.getSeconds()).padStart(2,'0')
    return `${y}-${m}-${da} ${h}:${f}:${s}`
    }
    module.exports = {
    updateToken,
    searchQuestion
    }
    主程序main.js
    1
    2
    3
    4
    5
    6
    7
    const {updateToken,searchQuestion} = require('./searchQuestion')
    async function main(){
    await updateToken(true,1000*60*60*24*7)
    let s = await searchQuestion('中国辛亥革命')
    console.log(s)
    }
    main()
    运行结果:

结尾

可惜了,账号被封掉了。进度被打断。