JAVA——基于HttpClient的正方教务系统[1999-2020]模拟登录|模拟退出|课程查询|成绩查询|考试查询基本解决方案
生活随笔
收集整理的這篇文章主要介紹了
JAVA——基于HttpClient的正方教务系统[1999-2020]模拟登录|模拟退出|课程查询|成绩查询|考试查询基本解决方案
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
簡介?
通過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()))); // 將公鑰和私鑰保存到MapkeyMap.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();}//登錄URLprivate final String LOGIN_URL="http://XXXXXX.zstu.edu.cn/jwglxt/xtgl/login_slogin.html?language=zh_CN&_t=";//RSA URLprivate final String PUBLICKEY_URL="http://XXXXXX.zstu.edu.cn/jwglxt/xtgl/login_getPublicKey.html?time=";//退出URLprivate final String LOGOUT_URL="http://XXXXXX.zstu.edu.cn/jwglxt/logout?login_type=&t=";//課程URLprivate final String CHECK_COURSE_URL="http://XXXXXX.zstu.edu.cn/jwglxt/kbcx/xskbcx_cxXsKb.html?doType=query&gnmkdm=N2151";//成績URLprivate final String CHECK_GRADE_URL="http://XXXXXX.zstu.edu.cn/jwglxt/cjcx/cjcx_cxDgXscj.html?doType=query&gnmkdm=N305005";//考試URLprivate 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
總結
以上是生活随笔為你收集整理的JAVA——基于HttpClient的正方教务系统[1999-2020]模拟登录|模拟退出|课程查询|成绩查询|考试查询基本解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Boot——读取.prop
- 下一篇: JAVA——HttpClient封装工具