簡介
通過HttpClient獲取網頁數據源,通過Jsoup解析數據。先模擬登錄,再獲取信息。模擬瀏覽器正常操作,封裝請求頭信息獲取SESSIONID。模擬登錄成功後切勿斷開會話,依賴登錄請求得到的Cookie進行二次請求。請求信息時需打開谷歌瀏覽器或Fiddler抓包查看參數及請求頭信息。
Maven
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
基本步驟
1.獲取exponent、modulus生成公鑰進行密碼加密
2.爬蟲爬取csrftoken校驗
3.添加Post參數模擬瀏覽器登錄獲取Cookie(SESSIONID)
4.二次請求
源代碼
Util
package club.zstuca.util;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
public class RSAUtil {
private static Map<Integer, String> keyMap = new HashMap<Integer, String>(); //用於封裝隨機產生的公鑰與私鑰
/**
* 隨機生成密鑰對
* @throws NoSuchAlgorithmException
*/
public static void genKeyPair() throws NoSuchAlgorithmException {
// KeyPairGenerator類用於生成公鑰和私鑰對,基於RSA算法生成對象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密鑰對生成器,密鑰大小爲96-1024位
keyPairGen.initialize(1024,new SecureRandom());
// 生成一個密鑰對,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私鑰
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公鑰
String publicKeyString = new String(Base64.getEncoder().encode(publicKey.getEncoded()));
// 得到私鑰字符串
String privateKeyString = new String(Base64.getEncoder().encode((privateKey.getEncoded())));
// 將公鑰和私鑰保存到Map
keyMap.put(0,publicKeyString); //0表示公鑰
keyMap.put(1,privateKeyString); //1表示私鑰
}
/**
* RSA公鑰加密
*
* @param str
* 加密字符串
* @param publicKey
* 公鑰
* @return 密文
* @throws Exception
* 加密過程中的異常信息
*/
public static String encryptByX509EncodedKeySpec( String str, String publicKey ) throws Exception{
//base64編碼的公鑰
byte[] decoded = Base64.getDecoder().decode(publicKey.getBytes("UTF-8"));
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8")));
return outStr;
}
/**
* RSA公鑰加密
*
* @param str
* 加密字符串
* @param modulus
* 模數
* @param publicExponent
* 公衆指數
* @return 密文
* @throws Exception
* 加密過程中的異常信息
*/
public static String encryptByRSAPublicKeySpec( String str, String modulus, String publicExponent ) throws Exception{
//base64編碼的公鑰
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
.generatePublic(new RSAPublicKeySpec(
new BigInteger(1,Base64.getDecoder().decode(modulus.getBytes("UTF-8"))),
new BigInteger(1,Base64.getDecoder().decode(publicExponent.getBytes("UTF-8")))
));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8")));
return outStr;
}
/**
* RSA私鑰解密
*
* @param str
* 加密字符串
* @param privateKey
* 私鑰
* @return 銘文
* @throws Exception
* 解密過程中的異常信息
*/
public static String decryptByPKCS8EncodedKeySpec(String str, String privateKey) throws Exception{
//64位解碼加密後的字符串
byte[] inputByte = Base64.getDecoder().decode(str.getBytes("UTF-8"));
//base64編碼的私鑰
byte[] decoded = Base64.getDecoder().decode(privateKey.getBytes("UTF-8"));
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
}
Main
package cn.edu.newedu;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import com.alibaba.fastjson.JSON;
import cn.edu.zstu.beans.Grade;
import cn.edu.zstu.beans.Course;
import cn.edu.zstu.beans.Exam;
import cn.edu.zstu.util.RSAUtil;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
public class ZFsoft {
public static void main(String[] args) {
ZFsoft zFsoft=new ZFsoft();
zFsoft.login("2018329621200","XXXXXX");
List<Course>courseList=zFsoft.checkCourse("2019","12");
for(Course course:courseList){
System.out.println(course);
}
System.out.println(courseList.size());
List<Grade>gradeList=zFsoft.checkScore("","");
for(Grade grade:gradeList){
System.out.println(grade);
}
System.out.println(gradeList.size());
List<Exam>examList=zFsoft.checkExam("","");
for(Exam exam:examList){
System.out.println(exam);
}
System.out.println(examList.size());
zFsoft.logout();
}
//登錄URL
private final String LOGIN_URL="http://XXXXXX.zstu.edu.cn/jwglxt/xtgl/login_slogin.html?language=zh_CN&_t=";
//RSA URL
private final String PUBLICKEY_URL="http://XXXXXX.zstu.edu.cn/jwglxt/xtgl/login_getPublicKey.html?time=";
//退出URL
private final String LOGOUT_URL="http://XXXXXX.zstu.edu.cn/jwglxt/logout?login_type=&t=";
//課程URL
private final String CHECK_COURSE_URL="http://XXXXXX.zstu.edu.cn/jwglxt/kbcx/xskbcx_cxXsKb.html?doType=query&gnmkdm=N2151";
//成績URL
private final String CHECK_GRADE_URL="http://XXXXXX.zstu.edu.cn/jwglxt/cjcx/cjcx_cxDgXscj.html?doType=query&gnmkdm=N305005";
//考試URL
private final String CHECK_EXAM_URL="http://XXXXXX.zstu.edu.cn/jwglxt/kwgl/kscx_cxXsksxxIndex.html?doType=query&gnmkdm=N358105";
private CloseableHttpClient httpClient;
private BasicCookieStore basicCookieStore;
public ZFsoft(){
basicCookieStore=new BasicCookieStore();
httpClient= HttpClients
.custom()
.setDefaultCookieStore(basicCookieStore)
.build();
}
/**
* 密碼加密 RSA
* @param password
* @return
*/
private String encryp(String password){
//一、獲取 exponent modulus 生成公鑰
String exponent=null,modulus=null;
HttpGet gpkHttpGet=
new HttpGet(PUBLICKEY_URL+new Date().getTime());
gpkHttpGet.setHeader("Accept","application/json, text/javascript, */*; q=0.01");
gpkHttpGet.setHeader("Accept-Encoding","gzip, deflate");
gpkHttpGet.setHeader("Accept-Language","zh-CN,zh;q=0.9");
gpkHttpGet.setHeader("Connection","keep-alive");
gpkHttpGet.setHeader("Host","jwglxt.zstu.edu.cn");
gpkHttpGet.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36");
gpkHttpGet.setHeader("X-Requested-With","XMLHttpRequest");
CloseableHttpResponse gpkResponse=null;
try {
gpkResponse = httpClient.execute(gpkHttpGet);
if (gpkResponse.getStatusLine().getStatusCode() == 200) {
String emJson = EntityUtils.toString(gpkResponse.getEntity(), "utf8");
JSONObject jsonObject = new JSONObject(emJson);
exponent = jsonObject.getString("exponent");
modulus = jsonObject.getString("modulus");
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
gpkResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//二、根據公鑰進行密碼加密
System.out.println(modulus);
System.out.println(exponent);
System.out.println(password);
try {
password=RSAUtil.encryptByRSAPublicKeySpec(password, modulus, exponent);
} catch (Exception e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
System.out.println(password);
return password;
}
/**
* 獲取Token
* @param timestamp
* @return
*/
private String crawlCsrfToken(String timestamp){
String csrftoken=null;
HttpGet csrftokenHttpGet=
new HttpGet(LOGIN_URL+timestamp);
CloseableHttpResponse csrftokenResponse=null;
try {
csrftokenResponse = httpClient.execute(csrftokenHttpGet);
if (csrftokenResponse.getStatusLine().getStatusCode() == 200) {
Document csrftokenDoc = Jsoup.parse(EntityUtils.toString(csrftokenResponse.getEntity(), "utf8"));
csrftoken = csrftokenDoc
.select(".col-sm-4")
.select(".sl_log_rt")
.select("input[id=csrftoken]")
.first()
.attr("value");
return csrftoken;
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
csrftokenResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 模擬登錄
* @param username
* @param password
* @return
*/
public ZFsoft login(String username,String password){
String timestamp=""+new Date().getTime();
HttpPost loginHttpPost=new HttpPost(LOGIN_URL+timestamp);
loginHttpPost.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
loginHttpPost.setHeader("Accept-Encoding","gzip, deflate");
loginHttpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9");
loginHttpPost.setHeader("Cache-Control","max-age=0");
loginHttpPost.setHeader("Connection","keep-alive");
loginHttpPost.setHeader("Content-Type","application/x-www-form-urlencoded");
loginHttpPost.setHeader("Host","jwglxt.zstu.edu.cn");
loginHttpPost.setHeader("Origin","http://jwglxt.zstu.edu.cn");
loginHttpPost.setHeader("Upgrade-Insecure-Requests","1");
loginHttpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36");
List<NameValuePair> loginParams=new ArrayList<NameValuePair>();
password=this.encryp(password);
String csrftoken=this.crawlCsrfToken(timestamp);
loginParams.add(new BasicNameValuePair("csrftoken",csrftoken));
loginParams.add(new BasicNameValuePair("yhm",username));
loginParams.add(new BasicNameValuePair("mm",password));
loginParams.add(new BasicNameValuePair("mm",password));
CloseableHttpResponse loginResponse=null;
try {
loginHttpPost.setEntity(new UrlEncodedFormEntity(loginParams, "utf8"));
loginResponse = httpClient.execute(loginHttpPost);
List<Cookie>cookies=basicCookieStore.getCookies();
if(cookies.isEmpty()){
System.out.println("The Cookie Is None.");
}else {
for(Cookie cookie:cookies){
System.out.println(cookie.getName() + " : " + cookie.getValue());
}
}
}catch (Exception e){
e.printStackTrace();
}
return this;
}
/**
* 退出
* @return
*/
public boolean logout() {
String timestamp=""+new Date().getTime();
HttpPost loginHttpPost=new HttpPost(LOGOUT_URL+timestamp);
loginHttpPost.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
loginHttpPost.setHeader("Accept-Encoding","gzip, deflate");
loginHttpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9");
loginHttpPost.setHeader("Cache-Control","max-age=0");
loginHttpPost.setHeader("Connection","keep-alive");
loginHttpPost.setHeader("Content-Type","application/x-www-form-urlencoded");
loginHttpPost.setHeader("Host","jwglxt.zstu.edu.cn");
loginHttpPost.setHeader("Origin","http://jwglxt.zstu.edu.cn");
loginHttpPost.setHeader("Upgrade-Insecure-Requests","1");
loginHttpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36");
CloseableHttpResponse loginResponse=null;
try {
loginResponse = httpClient.execute(loginHttpPost);
List<Cookie>cookies=basicCookieStore.getCookies();
if(cookies.isEmpty()){
System.out.println("The Cookie Is None.");
}else {
for(Cookie cookie:cookies){
System.out.println(cookie.getName() + " : " + cookie.getValue());
}
}
}catch (Exception e){
e.printStackTrace();
}
return true;
}
public List<Course> checkCourse(String xnm,String xqm){
HttpPost courseHttpPost=new HttpPost(CHECK_COURSE_URL);
courseHttpPost.setHeader("Accept","application/json, text/javascript, */*; q=0.01");
courseHttpPost.setHeader("Accept-Encoding","gzip, deflate");
courseHttpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9");
courseHttpPost.setHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
courseHttpPost.setHeader("Host","jwglxt.zstu.edu.cn");
courseHttpPost.setHeader("Origin","http://jwglxt.zstu.edu.cn");
courseHttpPost.setHeader("Proxy-Connection","keep-alive");
courseHttpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36");
courseHttpPost.setHeader("X-Requested-With","XMLHttpRequest");
List<NameValuePair>courseParams=new ArrayList<NameValuePair>();
courseParams.add(new BasicNameValuePair("xnm",xnm));
courseParams.add(new BasicNameValuePair("xqm",xqm));
List<Course> res = new LinkedList<>();
try {
courseHttpPost.setEntity(new UrlEncodedFormEntity(courseParams, "utf8"));
CloseableHttpResponse courseResponse = httpClient.execute(courseHttpPost);
if (courseResponse.getStatusLine().getStatusCode() == 200) {
if (courseResponse.getEntity() != null) {
String courseJson = EntityUtils.toString(courseResponse.getEntity(), "utf8");
System.out.print(courseJson);
if(courseResponse==null||courseResponse.equals("")|| !JSON.isValid(courseJson)){
return res;
}
JSONObject jsonObject = new JSONObject(courseJson);
JSONArray jsonArray = jsonObject.getJSONArray("kbList");
for (int i = 0; i < jsonArray.length(); ++i) {
JSONObject item = (JSONObject) jsonArray.get(i);
Course course= new Course();
course.setDay(item.getString("xqjmc"));
course.setPeriod(item.getString("jc"));
course.setLength(item.getString("month"));
course.setName(item.getString("kcmc"));
course.setType("一般課");
course.setTeacher(item.getString("xm"));
course.setRoom(item.getString("cdmc"));
course.setWeek(item.getString("zcd"));
res.add(course);
}
jsonArray = jsonObject.getJSONArray("sjkList");
for (int i = 0; i < jsonArray.length(); ++i) {
JSONObject item = (JSONObject) jsonArray.get(i);
Course course= new Course();
course.setName(item.getString("sjkcgs"));
course.setType("實踐課");
course.setTeacher(item.getString("sjkcgs"));
res.add(course);
}
return res;
}
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
/**
* 查看成績
* @param xnm
* @param xqm
* @return
*/
public List<Grade> checkScore(String xnm,String xqm){
HttpPost scoreHttpPost=new HttpPost(CHECK_GRADE_URL);
scoreHttpPost.setHeader("Accept","application/json, text/javascript, */*; q=0.01");
scoreHttpPost.setHeader("Accept-Encoding","gzip, deflate");
scoreHttpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9");
scoreHttpPost.setHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
scoreHttpPost.setHeader("Host","jwglxt.zstu.edu.cn");
scoreHttpPost.setHeader("Origin","http://jwglxt.zstu.edu.cn");
scoreHttpPost.setHeader("Proxy-Connection","keep-alive");
scoreHttpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36");
scoreHttpPost.setHeader("X-Requested-With","XMLHttpRequest");
List<NameValuePair>scoreParams=new ArrayList<NameValuePair>();
scoreParams.add(new BasicNameValuePair("xnm",xnm));
scoreParams.add(new BasicNameValuePair("xqm",xqm));
scoreParams.add(new BasicNameValuePair("_search","false"));
scoreParams.add(new BasicNameValuePair("nd",""+new Date().getTime()));
scoreParams.add(new BasicNameValuePair("queryModel.showCount","100"));
scoreParams.add(new BasicNameValuePair("queryModel.currentPage","1"));
scoreParams.add(new BasicNameValuePair("queryModel.sortName",""));
scoreParams.add(new BasicNameValuePair("queryModel.sortOrder","asc"));
scoreParams.add(new BasicNameValuePair("time","1"));
List<Grade> res = new LinkedList<Grade>();
try {
scoreHttpPost.setEntity(new UrlEncodedFormEntity(scoreParams, "utf8"));
CloseableHttpResponse scoreResponse = httpClient.execute(scoreHttpPost);
if (scoreResponse.getStatusLine().getStatusCode() == 200) {
if (scoreResponse.getEntity() != null) {
String scoreJson = EntityUtils.toString(scoreResponse.getEntity(), "utf8");
System.out.print(scoreJson);
JSONObject jsonObject = new JSONObject(scoreJson);
JSONArray jsonArray = jsonObject.getJSONArray("items");
for (int i = 0; i < jsonArray.length(); ++i) {
Grade grade = new Grade();
JSONObject item = (JSONObject) jsonArray.get(i);
try {
grade.setYear(item.getString("xnmmc"));
grade.setTerm(item.getString("xqm"));
grade.setCourseName(item.getString("kcmc"));
grade.setCredit(item.getString("xf"));
String gr = "";
// 有補考成績 則算補考成績
gr = new String(item.getString("ksxz").getBytes("UTF-8")).replace("?","");
if(!gr.equals("")) {
grade.setGrade(item.getString("cj"));
}
else {
grade.setGrade(item.getString("cj"));
}
grade.setGpa(item.getString("jd"));
res.add(grade);
}
catch(Exception e) {
e.printStackTrace();
}
}
return res;
}
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public List<Exam> checkExam(String xnm,String xqm){
HttpPost examHttpPost=new HttpPost(CHECK_EXAM_URL);
examHttpPost.setHeader("Accept","application/json, text/javascript, */*; q=0.01");
examHttpPost.setHeader("Accept-Encoding","gzip, deflate");
examHttpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9");
examHttpPost.setHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
examHttpPost.setHeader("Host","jwglxt.zstu.edu.cn");
examHttpPost.setHeader("Origin","http://jwglxt.zstu.edu.cn");
examHttpPost.setHeader("Proxy-Connection","keep-alive");
examHttpPost.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36");
examHttpPost.setHeader("X-Requested-With","XMLHttpRequest");
List<NameValuePair>examParams=new ArrayList<NameValuePair>();
examParams.add(new BasicNameValuePair("xnm","2019"));
examParams.add(new BasicNameValuePair("xqm","3"));
examParams.add(new BasicNameValuePair("_search","false"));
examParams.add(new BasicNameValuePair("ksmcdmb_id","2019-20201QN"));
examParams.add(new BasicNameValuePair("kch",""));
examParams.add(new BasicNameValuePair("kc",""));
examParams.add(new BasicNameValuePair("ksrq",""));
examParams.add(new BasicNameValuePair("nd",""+new Date().getTime()));
examParams.add(new BasicNameValuePair("queryModel.showCount","100"));
examParams.add(new BasicNameValuePair("queryModel.currentPage","1"));
examParams.add(new BasicNameValuePair("queryModel.sortName",""));
examParams.add(new BasicNameValuePair("queryModel.sortOrder","asc"));
examParams.add(new BasicNameValuePair("time","1"));
List<Exam> res = new LinkedList<>();
try {
examHttpPost.setEntity(new UrlEncodedFormEntity(examParams, "utf8"));
CloseableHttpResponse examResponse = httpClient.execute(examHttpPost);
if (examResponse.getStatusLine().getStatusCode() == 200) {
if (examResponse.getEntity() != null) {
String examJson = EntityUtils.toString(examResponse.getEntity(), "utf8");
System.out.print(examJson);
if(examJson==null||examJson.equals("")|| !JSON.isValid(examJson)){
return res;
}
JSONObject jsonObject = new JSONObject(examJson);
JSONArray jsonArray = jsonObject.getJSONArray("items");
for (int i = 0; i < jsonArray.length(); ++i) {
Exam exam = new Exam();
JSONObject item = (JSONObject) jsonArray.get(i);
exam.setCourseName(item.getString("kcmc"));
exam.setSeatNumber(item.getString("zwh"));
exam.setExamPlace(item.getString("cdmc"));
exam.setExamTime(item.getString("kssj"));
res.add(exam);
}
return res;
}
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
運行結果
Cookies:
課程:
成績:
考試:
參考文章
https://www.cnblogs.com/hbsdljz/p/10874099.html
https://shentuzhigang.blog.csdn.net/article/details/103995547
https://shentuzhigang.blog.csdn.net/article/details/103996741