问卷星相关参数

问卷星反爬手段越来越丧心病狂,截至目前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

<think>好的,我现在需要处理用户关于问卷API对接的请求。首先,用户想知道如何将问卷与第三方平台或服务进行集成,具体是教程方面的指导。根据用户提供的引用内容,特别是引用[2],里面提到问卷的编程接口允许用户创建、修改、发布和获取问卷结果,这应该是关键点。 首先,我需要整理API对接的基本步骤。通常,API对接需要注册账号、获取API密钥,然后根据文档进行接口调用。用户提到的引用[1]也提到API使能力提供方和使用方分离,所以需要强调注册和获取凭证的重要性。 接下来,我需要确保回答结构清晰,分步骤说明。可能需要包括注册获取API Key、阅读文档、调用接口的示例,以及错误处理等。同时,用户可能需要代码示例,但根据引用[2]中的示例,用户可能期望看到类似Python的代码片段,但需要确认问卷API的具体要求,比如是否支持RESTful,使用什么认证方式。 还需要注意用户提到的引用[3],虽然主要是作者的背景,但可能暗示用户希望有可靠的技术指导,因此回答需要专业且详细,可能包括创建问卷、获取结果的具体API端点,以及如何处理返回的数据。 另外,用户要求生成相关问题,可能需要包括API权限申请、数据安全、错误排查等。需要确保问题相关且有帮助,引导用户深入思考。 最后,检查是否符合格式要求:中文回答、行内公式正确(如果有的话)、独立公式单独成段,但这里可能不太涉及数学公式。需要确保没有使用Markdown,段落间用空行分隔,引用标识正确添加。例如,在提到API对接模式时引用[1],在代码示例部分引用[2]。 可能还需要补充关于API的具体功能,比如创建问卷、获取结果等,如何通过HTTP请求实现,可能需要给出具体的API URL示例,请求方法(GET/POST),以及参数说明。同时,提醒用户注意API调用频率限制、数据格式(JSON/XML)等细节。 总结步骤应该是:注册获取API Key,查阅官方文档,编写调用代码,处理响应,错误处理。每个步骤需要简明扼要,并附上示例代码,如Python的requests库使用。同时,确保引用正确,比如在提到API对接模式时引用[1],在代码示例部分引用[2]。</think>要对接问卷API并实现与第三方平台的集成,需按照以下步骤操作: --- ### 一、注册并获取API凭证 1. **登录问卷开放平台** 访问问卷开发者中心,注册账号并创建应用。通常需要提供企业或开发者信息以获取API权限。 2. **申请API Key和Secret** 在控制台中生成API密钥对,用于身份验证。例如: ```python API_KEY = "your_api_key" API_SECRET = "your_api_secret" ``` --- ### 二、调用API接口 问卷API支持多种操作,如创建问卷、获取数据等。以下以获取问卷结果为例: 1. **HTTP请求示例(Python)** ```python import requests # 认证与请求头 headers = { "API-Key": API_KEY, "API-Secret": API_SECRET, "Content-Type": "application/json" } # 获取问卷结果 response = requests.get( "https://api.wjx.cn/v1/surveys/{survey_id}/responses", headers=headers ) # 解析JSON响应 if response.status_code == 200: data = response.json() print("问卷结果:", data) else: print("请求失败:", response.text) ``` 此代码通过API拉取指定问卷的响应数据[^2]。 2. **常用API功能** - **创建问卷**:`POST /v1/surveys` - **发布问卷**:`POST /v1/surveys/{survey_id}/publish` - **导出数据**:`GET /v1/surveys/{survey_id}/responses/export` --- ### 三、业务集成与封装 1. **封装API调用** 根据业务需求,将问卷API封装为内部服务接口。例如,将问卷提交结果同步至CRM系统: ```python def sync_to_crm(survey_id): responses = get_survey_responses(survey_id) # 调用问卷API for resp in responses: crm_api.create_lead(resp[&#39;user_info&#39;], resp[&#39;answers&#39;]) # 同步至第三方平台 ``` 这种分层设计可保障业务隔离性[^1]。 2. **数据处理与校验** - 校验API返回的数据完整性(如字段缺失、格式异常) - 设置重试机制应对网络波动 --- ### 四、注意事项 1. **频率限制** 问卷API通常有调用次数限制(如100次/分钟),需设计合理的缓存策略。 2. **数据安全** 敏感数据(如API密钥)应通过环境变量或密钥管理服务存储,避免硬编码。 3. **错误码处理** 需处理常见错误码,如`401(认证失败)`、`404(问卷不存在)`等。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值