问卷星相关参数

问卷星反爬手段越来越丧心病狂,截至目前2021.10.18,提交参数已有13个之多,肝了几天,终于把最恶心的jqParam参数搞定,顺便记录下其他相关参数的生成及获取过程

提交参数分析

https://ks.wjx.top/joinnew/processjq.ashx?shortid=PpH6DjX&starttime=2021%2F10%2F18%2014%3A37%3A56&source=directphone&submittype=1&ktimes=79&hlv=1&rn=1975429446.43363516&jqpram=MHieF5pMt&jcn=%E5%A7%9A%E5%90%84&iwx=1&t=1634539304658&jqnonce=daa66ca2-ed5b-4434-85df-9c4a4ed13ee2&jqsign=mhh%3F%3Fjh%3B%24lm%3Ck%24%3D%3D%3A%3D%241%3Cmo%240j%3Dh%3Dlm8%3All%3B

如上是一次提交的相关参数,其中包括shortIdstarttimesourcesubmittypektimeshlvrnjqpramjcniwxtjqnonce以及jqsign,不过令人庆幸的是,相当一部分参数是可以直接在页面中获取或是固定值的,给我们减少了很大的工作量!泪目!

参数分类

上述13个参数大致可分为三大类,分别是:固定参数可从页面获取参数计算参数

固定参数

此类参数在自己测试过程中发现其值为固定值,到目前为止还没有发现有变化的情况,大佬们仅供参考,它们分别是:

  • submittype:固定值为1 (tips: 此参数好像是标识问卷类型,自己一直做的是“考试、试卷”类型,因此该值并未发现有变化,如是其他类型答卷请自行调整)
  • hlv:固定值1
  • iwx:固定值1

可从页面获取参数

此类参数在请求页面时会附加在页面中,可以通过xpath定位或正则表达式自行获取,它们分别是:

  • shortid
  • source
  • starttime
  • jqnonce
  • rn
  • activityId(此参数并未在提交参数中,但是后续计算需要该数据进行运算)
    该类参数在不同的设备(如微信和PC)下其定位方式(xpath路径)不同,如做通用类爬虫请注意

计算参数

此类参数并不能直接获取,需要通过一定的运算才能获取

  • ktimes:随机数(此数据较为特殊,建议10-300内任意整数即可)
  • t:时间戳(毫秒级时间戳,暂没发现有何特殊时间,可以使用当前时间的时间戳)
  • jcn
  • jqsign
  • jqpram:最头疼的参数,代码混淆,需要花时间自己好好摸索
    jcnjqsign的计算相对较为简单,其计算方式如下
ctx = execjs.compile('''function dataenc(a, ktimes) {
	    var c, d, e, b = ktimes % 10;
	    for (0 == b && (b = 1),
	    c = [],
	    d = 0; d < a.length; d++)
	        e = a.charCodeAt(d) ^ b,
	        c.push(String.fromCharCode(e));
	    return c.join("")
	}''')
# jqsign
jqsign = ctx.call("dataenc", jqnonce, ktimes)

# jcn计算
jcn = ctx.call("dataenc", '姓名', ktimes)

jqpram的运算过程较为复杂,因为需要处理代码混淆,其js代码逻辑如下

function abcd3(_0x420610, _0x1b425f) {
    if (_0x420610 - 62 < 0) {
        var _0xea36a8 = _0x1b425f['substr'](_0x420610, 1);
        return _0xea36a8;
    }
    var _0x45571c = _0x420610 % 62;
    var _0x4e6181 = parseInt(_0x420610 / 62);
    return abcd3(_0x4e6181, _0x1b425f) + _0x1b425f['substr'](_0x45571c, 1);
}

function abcdx() {
    var _0x5314ef = ['3', '4', '2', '0', '1']
      , _0xbb87ee = 0x0;
    while (!![]) {
        switch (_0x5314ef[_0xbb87ee++]) {
        case '0':
            if (undefined || undefined)
                return ![];
            continue;
        case '1':
            return !![];
        case '2':
            if (false)
                return ![];
            continue;
        case '3':
            if (false)
                return ![];
            continue;
        case '4':
            if (undefined)
                return ![];
            continue;
        }
        break;
    }
}

function abcd4(_0x11dbf0, _0x1558df) {
    var _0x24b247 = ['1', '3', '0', '4', '2', '5']
      , _0x505c79 = 0;
    while (!![]) {
        switch (_0x24b247[_0x505c79++]) {
        case '0':
            var _0x27312b = _0x1558df.length;
            continue;
        case '1':
            if (!abcdx())
                return;
            continue;
        case '2':
            _0x1558df = _0x556c7b.join('');
            continue;
        case '3':
            var _0x556c7b = _0x1558df.split('');
            continue;
        case '4':
            for (var _0x107cfb = 0; _0x107cfb < _0x11dbf0.length; _0x107cfb++) {
                var _0x172a4c = ['0', '3', '2', '1', '4']
                  , _0x5ca706 = 0;
                while (!![]) {
                    switch (_0x172a4c[_0x5ca706++]) {
                    case '0':
                        var _0x410c33 = parseInt(_0x11dbf0[_0x107cfb]);
                        continue;
                    case '1':
                        _0x556c7b[_0x410c33] = _0x433a77;
                        continue;
                    case '2':
                        var _0x433a77 = _0x556c7b[_0x27312b - 1 - _0x410c33];
                        continue;
                    case '3':
                        var _0x43a652 = _0x556c7b[_0x410c33];
                        continue;
                    case '4':
                        _0x556c7b[_0x27312b - 1 - _0x410c33] = _0x43a652;
                        continue;
                    }
                    break;
                }
            }
            continue;
        case '5':
            return _0x1558df;
        }
        break;
    }
}

function abcd2(_0x1b1e02, _0x23f273) {
    var _0x303591 = "9|5|2|3|0|7|6|1|8|4".split('|')
    , _0x15e51e = 0x0;
    while (!![]) {
        switch (_0x303591[_0x15e51e++]) {
        case '0':
            var _0x470088 = ~~(_0x23f273 / _0x1f9ba1);
            continue;
        case '1':
            var _0x353774 = _0x4ad458 ^ _0x470088;
            continue;
        case '2':
            var _0x3b83ae = 2147483647;
            continue;
        case '3':
            var _0x4ad458 = ~~(_0x1b1e02 / _0x1f9ba1);
            continue;
        case '4':
            return _0x353774 * _0x1f9ba1 + _0x4a742c;
        case '5':
            var _0x1f9ba1 = 2147483648;
            continue;
        case '6':
            var _0x35dfa5 = _0x23f273 & _0x3b83ae;
            continue;
        case '7':
            var _0x5bc159 = _0x1b1e02 & _0x3b83ae;
            continue;
        case '8':
            var _0x4a742c = _0x5bc159 ^ _0x35dfa5;
            continue;
        case '9':
            if (!abcdx())
                return;
            continue;
        }
        break;
    }
}

function abcd1(_0x17164c) {
    return abcd2(_0x17164c, 3597397)
}

function abcd5(_0x5565b6) {
    var _0x3260f4 = "7|5|2|8|3|1|4|0|6|9".split('|')
      , _0x56f3ce = 0;
    while (!![]) {
        switch (_0x3260f4[_0x56f3ce++]) {
        case '0':
            for (var _0x28a6c3 = _0x5258e0; _0x28a6c3 < _0x5af006; _0x28a6c3++) {
                _0x2b24c5.push(_0x5ed7b1[_0x28a6c3]);
            }
            continue;
        case '1':
            var _0x5258e0 = _0x546e81 % _0x5af006;
            continue;
        case '2':
            var _0x5ed7b1 = _0x5565b6.split('');
            continue;
        case '3':
            var _0x5af006 = _0x5565b6.length;
            continue;
        case '4':
            var _0x2b24c5 = [];
            continue;
        case '5':
            var _0x546e81 = 0;
            continue;
        case '6':
            for (var _0x28a6c3 = 0; _0x28a6c3 < _0x5258e0; _0x28a6c3++) {
                _0x2b24c5.push(_0x5ed7b1[_0x28a6c3]);
            }
            continue;
        case '7':
            if (!abcdx())
                return;
            continue;
        case '8':
            for (var _0x28a6c3 = 0; _0x28a6c3 < _0x5ed7b1.length; _0x28a6c3++) {
                _0x546e81 += _0x5ed7b1[_0x28a6c3].charCodeAt();
            }
            continue;
        case '9':
            return _0x2b24c5.join('');
        }
        break;
    }
}

function get_jqParam(activityId, rndnum, time) {
    var _0x3098bf = rndnum.split('.')[0]
    var _0x4aaf4a = abcd1(parseInt(_0x3098bf))

    var _0x4eae39 = time // 当前时间时间戳
    var _0x5050a2 = _0x4eae39 + ''
    if (_0x4eae39 % 10 > 0)
        _0x5050a2 = _0x5050a2.split('').reverse().join('')
    _0xd16fcc = parseInt(_0x5050a2 + '89123')
    _0x149db2 = _0xd16fcc + '' + 1971866899 + ''
    _0x149db2 = _0x149db2.split('')
    _0x1b3de6 = abcd4(_0x149db2, 'kgESOLJUbB2fCteoQdYmXvF8j9IZs3K0i6w75VcDnG14WAyaxNqPuRlpTHMrhz')
    
    var _0x3a5cf2 = _0xd16fcc + _0x4aaf4a + parseInt(activityId ^ 2130030173)
    jqParam = abcd3(_0x3a5cf2, _0x1b3de6);

    _0x5d90fd = abcd5(jqParam)
    jqParam = _0x5d90fd

    return jqParam
}

计算时直接调用函数get_jqParam,其三个参数activityIdrndnum(就是之前获取的参数rn)及time(就是之前获取的参数t

### 如何从问卷导出或下载原始问卷设计文件 在问卷平台中,虽然其主要功能集中在在线问卷的设计、发布以及数据分析上,但它并未直接支持以某种标准格式(如PDF、DOCX等)导出完整的原始问卷设计文件。然而,用户可以采取一些间接的方法来获取接近于原始问卷设计的内容。 #### 方法一:通过导出预览实现近似还原 问卷提供了问卷预览功能,在完成问卷设计之后,可以通过浏览器打印页面的方式将其转换为PDF文档[^1]。具体操作如下: 1. 登录问卷账户并进入目标问卷编辑界面; 2. 利用右上方工具栏找到“预览”按钮,启动实时查看模式; 3. 使用浏览器自带的打印选项(通常快捷键为Ctrl+P),选择保存为目标PDF而非实际打印机设备。 这种方法生成的结果能够较为直观地展示整个问卷布局样式及其内容项,尽管并非严格意义上的原生电子版问卷文件形式。 #### 方法二:借助外部脚本提取JSON结构化数据 对于技术型使用者而言,还可以尝试利用编程手段抓取后台存储的相关元信息。例如基于Python语言编写爬虫程序访问特定URL地址获取包含所有问题描述在内的json对象表示法字符串表达式[^2]: ```python import requests url = 'https://www.wenjuan.com/api/v2/surveys/{survey_id}/questions' headers = { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', } response = requests.get(url, headers=headers) data = response.json() print(data) ``` 注意此代码片段仅作示意用途,请替换其中占位符部分的实际值后再运行测试。此外还需确保遵循相应服务条款规定合法合规使用API接口资源。 #### 方法三:手动记录整理成标准化文档模板 当上述两种途径均不可行或者不符合需求场景时,则可考虑最基础的手动复制粘贴方式将每道题目逐条录入到Word或其他文字处理软件当中形成正式版本材料[^3] 。这样做的好处在于完全掌控最终呈现效果的同时也便于后期进一步调整优化排版风格等等细节之处。 --- ### 数据兼容性注意事项 无论采用哪种策略获得所需资料后,在涉及到后续跨平台传输比如导入SPSS做深入统计分析之前务必确认好各项参数设定保持一致以免出现不必要的麻烦状况诸如乱码现象等问题发生几率大大增加 [^4] 。 另外关于含有反向计分类型的复杂量表类问卷则更应该谨慎对待每一个环节步骤以防差错影响到最后结论准确性评估价值降低等情况产生 [^5] 。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值