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>

基本步骤

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 club.zstuca.tools;

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 club.zstuca.util.RSAUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ZFsoft {
	public static void main(String[] args) {
        ZFsoft zFsoft=new ZFsoft();
        
        //zFsoft.login("2018329621200","xxxx");
        
        List<Score>scoreList=zFsoft
                .login("2018329621200","xxxx")
                .checkScore("","");
        for(Score score:scoreList){
            System.out.println(score);
        }
        System.out.println(scoreList.size());
    }
    private final String LOGIN_URL="http://10.11.247.52/jwglxt/xtgl/login_slogin.html?language=zh_CN&_t=";
    private final String PUBLICKEY_URL="http://10.11.247.52/jwglxt/xtgl/login_getPublicKey.html?time=";
    private final String CHECK_SCORE_URL="http://10.11.247.52/jwglxt/cjcx/cjcx_cxDgXscj.html?doType=query&gnmkdm=N305005";

    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","jwgl.hebtu.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","jwgl.hebtu.edu.cn");
        loginHttpPost.setHeader("Origin","http://jwgl.hebtu.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){

                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return this;
    }

    /**
     * 查看成绩
     * @param xnm
     * @param xqm
     * @return
     */
    public List<Score> checkScore(String xnm,String xqm){
        HttpPost scoreHttpPost=new HttpPost(CHECK_SCORE_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","jwgl.hebtu.edu.cn");
        scoreHttpPost.setHeader("Origin","http://jwgl.hebtu.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"));
        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");
                    List<Score>scoreList=new ArrayList<Score>();
                    for (int i = 0; i < jsonArray.length(); ++i) {
                        JSONObject item = (JSONObject) jsonArray.get(i);
                        Score score=new Score();
                        score.setXm(item.getString("xm"));
                        score.setKcmc(item.getString("kcmc"));
                        score.setBj(item.getString("bj"));
                        score.setCj(item.getString("cj"));
                        String jd = "0";
                        try {
                            jd = item.getString("jd");
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        score.setJd(jd);
                        score.setJgmc(item.getString("jgmc"));
                        score.setKch(item.getString("kch"));
                        score.setKcxzmc(item.getString("kcxzmc"));
                        score.setKsxz(item.getString("ksxz"));
                        scoreList.add(score);
                    }
                    return  scoreList;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}

运行结果

 

参考文章

https://www.cnblogs.com/hbsdljz/p/10874099.html

https://shentuzhigang.blog.csdn.net/article/details/103995547

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Starzkg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值