我又回来了

如果不说的话 这博客已经很久很久没更新过了 原因是一直以来都有事情(做项目) 实在是抽不开身 其实我本地也有几篇写了的文章 但是现在看来着实拉闸 所以就不打算推上来了 现在在准备考研 目标的话 先定个西南交大吧 拉闸了再说 研究方向主要定在大数据 或者是机器学习上 (实在是不太想做传统开发了)

事情起因

快考试了 很紧张 所以我需要复习起来 特别是做的练习题 但是题都是在微助教上 而且老师说没法导出来 在手机上看因为既有自己的答案 又有正确答案 所以很麻烦 我就想把他爬下来 然后导出到word文档里

准备工作

由于微助教是一个微信网页 理论上直接访问会被拦截掉 所以我第一步想的是抓包去看地址 但是后面觉得太麻烦 还要弄到一个局域网下 所以我又想通过微助教的PC网站去看下地址 结果我发现他PC端只有老师可以登录

于是我想到了利用微信网页端的做法 但是后面发现还是不行 因为微信网页端不能看到公众号

解决方案

最后我找到了微信的PC端 pc端比较好的事情就是可以查看源代码 这样就能找到地址了

后面的112是课号 139部分是试卷号 但是这个时候有个问题 就是由于是微信授权访问的 所以直接在浏览器上面访问会显示错误 因为这个时候其实是没有登录的 但是我发现了一个比较有意思的东西就是微信的pc端可以允许把页面在浏览器上打开

然后去看下请求 就很容易得到了 可以看到实际上他是做了分页 同时需要注意的就是微信公众号是每隔2个小时进行密匙更换的 所以他的openid不是微信的那个openid 而是他自己生成的 并且是带有时限的

最后从返回的结果中就可以看到 type是试题的类型 1是单选 2是多选 3是判断 4是填空 而且所有的答案数据都在answerContene中

Ok 到这里就能拿到所有数据的

导出到word文档里

由于时间太紧 所以我使用java写的 而且为了方便理解 我有些地方变量用的拼音(平时我一般不这么做) 用的poi写的 解析json用的阿里的fastJSON 还有解析文档的Jsoup 为了方便我都放到了一个文档里面 写的controller层

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
package com.szy.wechat.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.szy.wechat.service.TestService;
import com.szy.wechat.utils.HttpUtils;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.List;

@RestController
@RequestMapping("/test/wzj")
public class TestController {
@Autowired
private TestService testService;
@Autowired
private HttpUtils httpUtils;




@GetMapping
public void insert(HttpServletRequest request, HttpServletResponse response){
HashMap<String, String> header = new HashMap<>();
header.put("Cookie","UM_distinctid=16f070a85fa3a8-0e43fd216e6dd9-2393f61-1fa400-16f070a85fbd2b; CNZZDATA1258955147=1384001563-1576367302-%7C1576466494; session=eyJvcGVuSWQiOiIxMTUzNjM0MTU4YzFkYjNmMTMzNmYyMWU4MmU3NzA0NCJ9; session.sig=-5WoL80rGho7GUMmLRT1MVPqzcw");
header.put("Host","v18.teachermate.cn");
header.put("openId","1153634158c1db3f1336f21e82e77044");
header.put("Referer","http://v18.teachermate.cn/wechat-pro-ssr/student/answer-questions/1121350/papers/"+id+"?isWrongQuesPage=");
int count = 0;
StringBuilder shifei = new StringBuilder();
StringBuilder danxuan = new StringBuilder();
StringBuilder tiankong = new StringBuilder();
StringBuilder duoxuan = new StringBuilder();

for (int i = 0; i < 9; i++) {
String s = httpUtils.doGetHeader("http://v18.teachermate.cn/wechat-api/v3/students/papers/"+id+"/questions?page=" + i, header);
JSONArray objects = JSON.parseArray(s);
for (int i1 = 0; i1 < objects.size(); i1++) {
JSONObject jsonObject = objects.getJSONObject(i1);
int type = jsonObject.getInteger("type").intValue();
if (type==1){
//单选
count++;
danxuan.append(jsonObject.getString("content").replace("<p>","<p style='color:#0033FF'>"+count+". ")+"<br>");
JSONArray answerContent = jsonObject.getJSONArray("answerContent");
for (int i2 = 0; i2 < answerContent.size(); i2++) {
JSONObject danxuanitem = answerContent.getJSONObject(i2);

String content = danxuanitem.getString("content");
Boolean answer = danxuanitem.getBoolean("answer");
if (answer){
switch (i2){
case 0:
danxuan.append(content.replace("<p>","<p style='color:red'>A "));

break;
case 1:
danxuan.append(content.replace("<p>","<p style='color:red'>B "));

break;
case 2:
danxuan.append(content.replace("<p>","<p style='color:red'>C "));

break;
case 3:
danxuan.append(content.replace("<p>","<p style='color:red'>D "));
break;
default:
break;
}

}else {

switch (i2){
case 0:
danxuan.append(content.replace("<p>","<p>A "));
break;
case 1:
danxuan.append(content.replace("<p>","<p>B "));
break;
case 2:
danxuan.append(content.replace("<p>","<p>C "));
break;
case 3:
danxuan.append(content.replace("<p>","<p>D "));
break;
default:
break;
}

}
}
}else if (type==3){
//是非
count++;
shifei.append(jsonObject.getString("content").replace("<p>","<p style='color:#0033FF'>"+count+". ")+"<br>");
JSONArray answerContent = jsonObject.getJSONArray("answerContent");
JSONObject shifeiAnswer = answerContent.getJSONObject(0);
shifei.append("<p style='color:red'>"+shifeiAnswer.getString("content")+"</p>");
}else if (type==4){
//填空
count++;
tiankong.append(jsonObject.getString("content").replace("<p>","<p style='color:#0033FF'>"+count+". ")+"<br>");
JSONArray answerContent = jsonObject.getJSONArray("answerContent");
for (int i2 = 0; i2 < answerContent.size(); i2++) {
JSONObject tiankongitem = answerContent.getJSONObject(i2);
String content = tiankongitem.getString("content");
switch (i2){
case 0:
tiankong.append("① "+content.replace("[","").replace("]","").replace("\"","")+"<br>");
break;
case 1:
tiankong.append("② "+content.replace("[","").replace("]","").replace("\"","")+"<br>");
break;
case 2:
tiankong.append("③ "+content.replace("[","").replace("]","").replace("\"","")+"<br>");

break;
case 3:
tiankong.append("④ "+content.replace("[","").replace("]","").replace("\"","")+"<br>");

break;
default:
break;
}

}
}else {
//多选
count++;
duoxuan.append(jsonObject.getString("content").replace("<p>","<p style='color:#0033FF'>"+count+". ")+"<br>");
JSONArray answerContent = jsonObject.getJSONArray("answerContent");
for (int i2 = 0; i2 < answerContent.size(); i2++) {
JSONObject danxuanitem = answerContent.getJSONObject(i2);

String content = danxuanitem.getString("content");
Boolean answer = danxuanitem.getBoolean("answer");
if (answer){
switch (i2){
case 0:
duoxuan.append(content.replace("<p>","<p style='color:red'>A "));

break;
case 1:
duoxuan.append(content.replace("<p>","<p style='color:red'>B "));

break;
case 2:
duoxuan.append(content.replace("<p>","<p style='color:red'>C "));

break;
case 3:
duoxuan.append(content.replace("<p>","<p style='color:red'>D "));
break;
default:
break;
}
}else {
switch (i2){
case 0:
duoxuan.append(content.replace("<p>","<p>A "));
break;
case 1:
duoxuan.append(content.replace("<p>","<p>B "));
break;
case 2:
duoxuan.append(content.replace("<p>","<p>C "));
break;
case 3:
duoxuan.append(content.replace("<p>","<p>D "));
break;
default:
break;
}

}
}
}
}

}



try {
String con = "<html><body>"+danxuan.toString()+duoxuan.toString()+"<br><br><br><br>"+"<br><br><br><br>"+shifei.toString()+"<br><br><br><br>"+tiankong.toString()+"</body></html>";
byte[] bytes = con.getBytes("utf-8");
ByteArrayInputStream baisk = new ByteArrayInputStream(bytes);
POIFSFileSystem poifsFileSystem = new POIFSFileSystem();
DirectoryNode directory = poifsFileSystem.getRoot();
try {
DocumentEntry documentEntry = directory.createDocument("作业1", baisk);
request.setCharacterEncoding("utf-8");
response.setContentType("application/msword");//导出word格式
response.addHeader("Content-Disposition", "p_w_upload;filename=" +
new String( (documentEntry.getName() + ".doc").getBytes(), "iso-8859-1"));
OutputStream ostream = response.getOutputStream();
poifsFileSystem.writeFilesystem(ostream);
baisk.close();
ostream.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}


}

因为时间太仓促了 代码写的比较low 很多地方也没写成动态的 所以代码大家参考一下即可 我也是图方便 能用就行