經過HttpClient獲取網頁數據源,經過Jsoup解析數據。先模擬登陸,再獲取信息。模擬瀏覽器正常操做,封裝請求頭信息獲取SESSIONID。模擬登陸成功後切勿斷開會話,依賴登陸請求獲得的Cookie進行二次請求。請求信息時需打開谷歌瀏覽器或Fiddler抓包查看參數及請求頭信息。javascript
1 <dependency> 2 <groupId>com.baidu.aip</groupId> 3 <artifactId>java-sdk</artifactId> 4 <version>4.8.0</version> 5 </dependency> 6 <dependency> 7 <groupId>org.apache.httpcomponents</groupId> 8 <artifactId>httpclient</artifactId> 9 <version>4.5.2</version> 10 </dependency> 11 <dependency> 12 <groupId>org.jsoup</groupId> 13 <artifactId>jsoup</artifactId> 14 <version>1.11.3</version> 15 </dependency> 16 <dependency> 17 <groupId>org.apache.commons</groupId> 18 <artifactId>commons-lang3</artifactId> 19 <version>3.4</version> 20 </dependency> 21 <dependency> 22 <groupId>org.json</groupId> 23 <artifactId>json</artifactId> 24 <version>20160810</version> 25 </dependency>
1.獲取exponent、modulus生成公鑰進行密碼加密html
2.爬蟲爬取csrftoken校驗java
3.添加Post參數模擬瀏覽器登陸獲取Cookie(SESSIONID)node
4.二次請求web
1 public class B64 { 2 3 public static String b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 4 private static char b64pad = '='; 5 private static String hexCode = "0123456789abcdef"; 6 7 // 獲取對應16進制字符 8 public static char int2char(int a){ 9 return hexCode.charAt(a); 10 } 11 12 // Base64轉16進制 13 public static String b64tohex(String s) { 14 String ret = ""; 15 int k = 0; 16 int slop = 0; 17 for(int i = 0; i < s.length(); ++i) { 18 if(s.charAt(i) == b64pad) break; 19 int v = b64map.indexOf(s.charAt(i)); 20 if(v < 0) continue; 21 if(k == 0) { 22 ret += int2char(v >> 2); 23 slop = v & 3; 24 k = 1; 25 } 26 else if(k == 1) { 27 ret += int2char((slop << 2) | (v >> 4)); 28 slop = v & 0xf; 29 k = 2; 30 } 31 else if(k == 2) { 32 ret += int2char(slop); 33 ret += int2char(v >> 2); 34 slop = v & 3; 35 k = 3; 36 } 37 else { 38 ret += int2char((slop << 2) | (v >> 4)); 39 ret += int2char(v & 0xf); 40 k = 0; 41 } 42 } 43 if(k == 1) 44 ret += int2char(slop << 2); 45 return ret; 46 } 47 48 // 16進制轉Base64 49 public static String hex2b64(String h) { 50 int i , c; 51 StringBuilder ret = new StringBuilder(); 52 for(i = 0; i+3 <= h.length(); i+=3) { 53 c = parseInt(h.substring(i,i+3),16); 54 ret.append(b64map.charAt(c >> 6)); 55 ret.append(b64map.charAt(c & 63)); 56 } 57 if(i+1 == h.length()) { 58 c = parseInt(h.substring(i,i+1),16); 59 ret.append(b64map.charAt(c << 2)); 60 } 61 else if(i+2 == h.length()) { 62 c = parseInt(h.substring(i,i+2),16); 63 ret.append(b64map.charAt(c >> 2)); 64 ret.append(b64map.charAt((c & 3) << 4)); 65 } 66 while((ret.length() & 3) > 0) ret.append(b64pad); 67 return ret.toString(); 68 } 69 }
1 public class RSAEncoder { 2 private static BigInteger n = null; 3 private static BigInteger e = null; 4 5 public static String RSAEncrypt(String pwd, String nStr, String eStr){ 6 n = new BigInteger(nStr,16); 7 e = new BigInteger(eStr,16); 8 9 BigInteger r = RSADoPublic(pkcs1pad2(pwd,(n.bitLength()+7)>>3)); 10 String sp = r.toString(16); 11 if((sp.length()&1) != 0 ) 12 sp = "0" + sp; 13 return sp; 14 } 15 16 private static BigInteger RSADoPublic(BigInteger x){ 17 return x.modPow(e, n); 18 } 19 20 private static BigInteger pkcs1pad2(String s, int n){ 21 if(n < s.length() + 11) { // TODO: fix for utf-8 22 System.err.println("Message too long for RSAEncoder"); 23 return null; 24 } 25 byte[] ba = new byte[n]; 26 int i = s.length()-1; 27 while(i >= 0 && n > 0) { 28 int c = s.codePointAt(i--); 29 if(c < 128) { // encode using utf-8 30 ba[--n] = new Byte(String.valueOf(c)); 31 } 32 else if((c > 127) && (c < 2048)) { 33 ba[--n] = new Byte(String.valueOf((c & 63) | 128)); 34 ba[--n] = new Byte(String.valueOf((c >> 6) | 192)); 35 } else { 36 ba[--n] = new Byte(String.valueOf((c & 63) | 128)); 37 ba[--n] = new Byte(String.valueOf(((c >> 6) & 63) | 128)); 38 ba[--n] = new Byte(String.valueOf((c >> 12) | 224)); 39 } 40 } 41 ba[--n] = new Byte("0"); 42 byte[] temp = new byte[1]; 43 Random rdm = new Random(47L); 44 while(n > 2) { // random non-zero pad 45 temp[0] = new Byte("0"); 46 while(temp[0] == 0) 47 rdm.nextBytes(temp); 48 ba[--n] = temp[0]; 49 } 50 ba[--n] = 2; 51 ba[--n] = 0; 52 return new BigInteger(ba); 53 } 54 }
1 import org.apache.http.NameValuePair; 2 import org.apache.http.client.entity.UrlEncodedFormEntity; 3 import org.apache.http.client.methods.CloseableHttpResponse; 4 import org.apache.http.client.methods.HttpGet; 5 import org.apache.http.client.methods.HttpPost; 6 import org.apache.http.cookie.Cookie; 7 import org.apache.http.impl.client.BasicCookieStore; 8 import org.apache.http.impl.client.CloseableHttpClient; 9 import org.apache.http.impl.client.HttpClients; 10 import org.apache.http.message.BasicNameValuePair; 11 import org.apache.http.util.EntityUtils; 12 import org.json.JSONArray; 13 import org.json.JSONObject; 14 import org.jsoup.Jsoup; 15 import org.jsoup.nodes.Document; 16 17 import java.io.IOException; 18 import java.util.ArrayList; 19 import java.util.Date; 20 import java.util.List; 21 22 public class ZFsoft { 23 private final String LOGIN_URL="http://jwgl.hebtu.edu.cn/xtgl/login_slogin.html?language=zh_CN&_t="; 24 private final String PUBLICKEY_URL="http://jwgl.hebtu.edu.cn/xtgl/login_getPublicKey.html?time="; 25 private final String CHECK_SCORE_URL="http://jwgl.hebtu.edu.cn/cjcx/cjcx_cxDgXscj.html?doType=query&gnmkdm=N305005"; 26 27 private CloseableHttpClient httpClient; 28 private BasicCookieStore basicCookieStore; 29 public ZFsoft(){ 30 basicCookieStore=new BasicCookieStore(); 31 httpClient= HttpClients 32 .custom() 33 .setDefaultCookieStore(basicCookieStore) 34 .build(); 35 } 36 37 /** 38 * 密碼加密 RSA 39 * @param password 40 * @return 41 */ 42 private String encryp(String password){ 43 //1、獲取 exponent modulus 生成公鑰 44 String exponent=null,modulus=null; 45 HttpGet gpkHttpGet= 46 new HttpGet(PUBLICKEY_URL+new Date().getTime()); 47 gpkHttpGet.setHeader("Accept","application/json, text/javascript, */*; q=0.01"); 48 gpkHttpGet.setHeader("Accept-Encoding","gzip, deflate"); 49 gpkHttpGet.setHeader("Accept-Language","zh-CN,zh;q=0.9"); 50 gpkHttpGet.setHeader("Connection","keep-alive"); 51 gpkHttpGet.setHeader("Host","jwgl.hebtu.edu.cn"); 52 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"); 53 gpkHttpGet.setHeader("X-Requested-With","XMLHttpRequest"); 54 CloseableHttpResponse gpkResponse=null; 55 try { 56 gpkResponse = httpClient.execute(gpkHttpGet); 57 if (gpkResponse.getStatusLine().getStatusCode() == 200) { 58 String emJson = EntityUtils.toString(gpkResponse.getEntity(), "utf8"); 59 JSONObject jsonObject = new JSONObject(emJson); 60 exponent = jsonObject.getString("exponent"); 61 modulus = jsonObject.getString("modulus"); 62 } 63 }catch (Exception e){ 64 e.printStackTrace(); 65 }finally { 66 try { 67 gpkResponse.close(); 68 } catch (IOException e) { 69 e.printStackTrace(); 70 } 71 } 72 //2、根據公鑰進行密碼加密 73 password=RSAEncoder.RSAEncrypt(password,B64.b64tohex(modulus),B64.b64tohex(exponent)); 74 password=B64.hex2b64(password); 75 return password; 76 } 77 78 /** 79 * 獲取Token 80 * @param timestamp 81 * @return 82 */ 83 private String crawlCsrfToken(String timestamp){ 84 String csrftoken=null; 85 HttpGet csrftokenHttpGet= 86 new HttpGet(LOGIN_URL+timestamp); 87 CloseableHttpResponse csrftokenResponse=null; 88 try { 89 csrftokenResponse = httpClient.execute(csrftokenHttpGet); 90 if (csrftokenResponse.getStatusLine().getStatusCode() == 200) { 91 Document csrftokenDoc = Jsoup.parse(EntityUtils.toString(csrftokenResponse.getEntity(), "utf8")); 92 csrftoken = csrftokenDoc 93 .select(".col-sm-4") 94 .select(".sl_log_rt") 95 .select("input[id=csrftoken]") 96 .first() 97 .attr("value"); 98 return csrftoken; 99 } 100 }catch (Exception e){ 101 e.printStackTrace(); 102 }finally { 103 try { 104 csrftokenResponse.close(); 105 } catch (IOException e) { 106 e.printStackTrace(); 107 } 108 } 109 return null; 110 } 111 112 /** 113 * 模擬登陸 114 * @param username 115 * @param password 116 * @return 117 */ 118 public ZFsoft login(String username,String password){ 119 String timestamp=""+new Date().getTime(); 120 HttpPost loginHttpPost=new HttpPost(LOGIN_URL+timestamp); 121 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"); 122 loginHttpPost.setHeader("Accept-Encoding","gzip, deflate"); 123 loginHttpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9"); 124 loginHttpPost.setHeader("Cache-Control","max-age=0"); 125 loginHttpPost.setHeader("Connection","keep-alive"); 126 loginHttpPost.setHeader("Content-Type","application/x-www-form-urlencoded"); 127 loginHttpPost.setHeader("Host","jwgl.hebtu.edu.cn"); 128 loginHttpPost.setHeader("Origin","http://jwgl.hebtu.edu.cn"); 129 loginHttpPost.setHeader("Upgrade-Insecure-Requests","1"); 130 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"); 131 List<NameValuePair> loginParams=new ArrayList<NameValuePair>(); 132 password=this.encryp(password); 133 String csrftoken=this.crawlCsrfToken(timestamp); 134 loginParams.add(new BasicNameValuePair("csrftoken",csrftoken)); 135 loginParams.add(new BasicNameValuePair("yhm",username)); 136 loginParams.add(new BasicNameValuePair("mm",password)); 137 loginParams.add(new BasicNameValuePair("mm",password)); 138 CloseableHttpResponse loginResponse=null; 139 try { 140 loginHttpPost.setEntity(new UrlEncodedFormEntity(loginParams, "utf8")); 141 loginResponse = httpClient.execute(loginHttpPost); 142 List<Cookie>cookies=basicCookieStore.getCookies(); 143 if(cookies.isEmpty()){ 144 System.out.println("The Cookie Is None."); 145 }else { 146 for(Cookie cookie:cookies){ 147 148 } 149 } 150 }catch (Exception e){ 151 e.printStackTrace(); 152 } 153 return this; 154 } 155 156 /** 157 * 查當作績 158 * @param xnm 159 * @param xqm 160 * @return 161 */ 162 public List<Score> checkScore(String xnm,String xqm){ 163 HttpPost scoreHttpPost=new HttpPost(CHECK_SCORE_URL); 164 scoreHttpPost.setHeader("Accept","application/json, text/javascript, */*; q=0.01"); 165 scoreHttpPost.setHeader("Accept-Encoding","gzip, deflate"); 166 scoreHttpPost.setHeader("Accept-Language","zh-CN,zh;q=0.9"); 167 scoreHttpPost.setHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8"); 168 scoreHttpPost.setHeader("Host","jwgl.hebtu.edu.cn"); 169 scoreHttpPost.setHeader("Origin","http://jwgl.hebtu.edu.cn"); 170 scoreHttpPost.setHeader("Proxy-Connection","keep-alive"); 171 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"); 172 scoreHttpPost.setHeader("X-Requested-With","XMLHttpRequest"); 173 List<NameValuePair>scoreParams=new ArrayList<NameValuePair>(); 174 scoreParams.add(new BasicNameValuePair("xnm",xnm)); 175 scoreParams.add(new BasicNameValuePair("xqm",xqm)); 176 scoreParams.add(new BasicNameValuePair("_search","false")); 177 scoreParams.add(new BasicNameValuePair("nd",""+new Date().getTime())); 178 scoreParams.add(new BasicNameValuePair("queryModel.showCount","100")); 179 scoreParams.add(new BasicNameValuePair("queryModel.currentPage","1")); 180 scoreParams.add(new BasicNameValuePair("queryModel.sortName","")); 181 scoreParams.add(new BasicNameValuePair("queryModel.sortOrder","asc")); 182 scoreParams.add(new BasicNameValuePair("time","1")); 183 try { 184 scoreHttpPost.setEntity(new UrlEncodedFormEntity(scoreParams, "utf8")); 185 CloseableHttpResponse scoreResponse = httpClient.execute(scoreHttpPost); 186 if (scoreResponse.getStatusLine().getStatusCode() == 200) { 187 if (scoreResponse.getEntity() != null) { 188 String scoreJson = EntityUtils.toString(scoreResponse.getEntity(), "utf8"); 189 JSONObject jsonObject = new JSONObject(scoreJson); 190 JSONArray jsonArray = jsonObject.getJSONArray("items"); 191 List<Score>scoreList=new ArrayList<Score>(); 192 for (int i = 0; i < jsonArray.length(); ++i) { 193 JSONObject item = (JSONObject) jsonArray.get(i); 194 Score score=new Score(); 195 score.setXm(item.getString("xm")); 196 score.setKcmc(item.getString("kcmc")); 197 score.setBj(item.getString("bj")); 198 score.setCj(item.getString("cj")); 199 String jd = "0"; 200 try { 201 jd = item.getString("jd"); 202 } catch (Exception e) { 203 e.printStackTrace(); 204 } 205 score.setJd(jd); 206 score.setJgmc(item.getString("jgmc")); 207 score.setKch(item.getString("kch")); 208 score.setKcxzmc(item.getString("kcxzmc")); 209 score.setKsxz(item.getString("ksxz")); 210 scoreList.add(score); 211 } 212 return scoreList; 213 } 214 } 215 }catch (Exception e){ 216 e.printStackTrace(); 217 } 218 return null; 219 } 220 }
1 public class Test { 2 public static void main(String[] args) { 3 ZFsoft zFsoft=new ZFsoft(); 4 List<Score>scoreList=zFsoft 5 .login("2016011493","密碼") 6 .checkScore("",""); 7 for(Score score:scoreList){ 8 System.out.println(score); 9 } 10 System.out.println(scoreList.size()); 11 } 12 }