简介
通过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