java爬虫---问卷星自动提交问卷请求参数(jqsign,jqnonce等)解密

以https://www.wjx.cn/jq/35713991.aspx这个问卷页为例

填完问卷打开控制台,转到network并且勾选preserver log(不然等会儿提交的请求看不到),点提交,找到此次提交请求如下:java爬虫---问卷星自动提交问卷请求参数(jqsign,jqnonce等)解密_第1张图片

是post请求,转到下面查看请求参数和post表单提交携带的参数(问卷答案):

java爬虫---问卷星自动提交问卷请求参数(jqsign,jqnonce等)解密_第2张图片

发现请求url里面带了9个参数。经过多次请求对比发现submittytype,curld,hlv没有变,其中不难发现curlid就是我们第一次请求https://www.wjx.cn/jq/35713991.aspx这个问卷页面的一个值,即代表了问卷id。

先说t和starttiem,爬虫参数多半是设置和时间有关,经过换算下当前时间毫秒数,基本接近t,因此判定t要么是出站时间要么是进站时间,经过下一次的对比(记录好进入问卷调查页面时间和点击提交的时间),确定了t是问卷提交时间的毫秒数,而starttime则是进入问卷调查页面的时间。

再说rn和jqnonce,我先爬取问卷页面,用jsoup解析返回的问卷html,在html中搜索得到了这两个值(在js中)。

最后一个jqsign,这个参数在js文件里面加密了。先来到问卷调查页面,打开控制台,选择提交按钮,定位到页面元素如下:

java爬虫---问卷星自动提交问卷请求参数(jqsign,jqnonce等)解密_第3张图片

这是一个表单提交按钮,再次在控制台定位到右边资源,选择事件监听,打开click标签,发现了提交触发的js:

java爬虫---问卷星自动提交问卷请求参数(jqsign,jqnonce等)解密_第4张图片

接着点进js文件,全部选中复制到站长这儿(http://tool.chinaz.com/Tools/jsformat.aspx)格式化之后在保存进自己的编辑器便于查看。接着在js文件里面搜关键字jqsign,如下图:

java爬虫---问卷星自动提交问卷请求参数(jqsign,jqnonce等)解密_第5张图片

发现在拼接字符串,就是在拼接提交表单的url,jqsign的值是b经过url编码的,在java可以使用如下方式进行编码解码:

URLEncoder.encode("S","UTF-8");
URLDecoder.decode("S","UTF-8");

那么再看上图的3,发现b是经过dataenc这个函数得来的,传入的参数正是之前获取到的jqnonce。

接着在js文件搜关键字dataenc得到如下函数:

 

java爬虫---问卷星自动提交问卷请求参数(jqsign,jqnonce等)解密_第6张图片

这即是jqsign参数加密的函数,先将ktime值取模,第二步我查了下优先级,发现是如果b为0那么就赋值为1,否则直接就使用b的值,然后紧接着for循环,charCodeAt和fromCharCode都是js的函数,分别是将字符串转为unicode编码和将unicode编码转为字符串。for循环第一步是将传入的a(即已知的jqnonce)每个字符转为unicode值之后再与b进行位运算,第二部是将位运算的结果转为字符串并且添加到d中,最后返回加密的字符串。在java中实现如下:(命名有点乱,测试用的)

public static String dataenc(String jqnonce) {
        int ktime = 365;
		// 模拟js算出jqsign
		StringBuffer g = new StringBuffer();
		String d[] = new String[]{};
		for (int c = 0; c < jqnonce.length(); c++) {
			int b = ktime % 10;
			if (b == 0) b = 1;

			char[] temp = jqnonce.toCharArray();
			String unicodeValue = getUnicode(temp[c]);

			int f = Integer.valueOf(unicodeValue.toString()).intValue() ^ b;

			if (c != 0) {
				g.append(",");
			}
			g.append(String.valueOf(f));
			String h = asciiToString(g.toString());

		}
		String jqsign = d.toString();
		System.out.println("rn   " + rn + "jqnonce  " + jqnonce + "  jqsign  " + jqsign);
}


//getUnicode函数
public static String getUnicode(char c) {
		String returnUniCode = null;
		returnUniCode = String.valueOf((int) c);
		return returnUniCode;

	}
/**
* Ascii转换为字符串
* 
* @param value
* @return
*/
public static String asciiToString(String value) {
	StringBuffer sbu = new StringBuffer();
	String[] chars = value.split(",");
	for (int i = 0; i < chars.length; i++) {
		sbu.append((char) Integer.parseInt(chars[i]));
	}
	return sbu.toString();
}

最后再模拟个表单提交,基本上就能完成自动答卷了(注意ip最好轮换)

                             以上内容仅做学习用途

你可能感兴趣的:(问题,总结,问卷星,爬虫,java,参数解密)