最近閑來(lái)無(wú)事,打算開(kāi)始寫(xiě)博客,也算是對(duì)自己知識(shí)的一個(gè)總結(jié)。本篇將講解如何使用HttpClient模擬登錄正方教務(wù)系統(tǒng)。
從策劃到設(shè)計(jì)制作,每一步都追求做到細(xì)膩,制作可持續(xù)發(fā)展的企業(yè)網(wǎng)站。為客戶提供網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)站策劃、網(wǎng)頁(yè)設(shè)計(jì)、域名注冊(cè)、雅安服務(wù)器托管、網(wǎng)絡(luò)營(yíng)銷、VI設(shè)計(jì)、 網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。為客戶提供更好的一站式互聯(lián)網(wǎng)解決方案,以客戶的口碑塑造優(yōu)易品牌,攜手廣大客戶,共同發(fā)展進(jìn)步。
需要使用道德jar包:HttpClient,Jsoup.(下載jar包)
本次模擬登錄的成都大學(xué)的教務(wù)系統(tǒng),其他學(xué)校的教務(wù)系統(tǒng),可參照本文給出的流程和代碼進(jìn)行修改并測(cè)試。
基本流程:
1).使用谷歌瀏覽器打開(kāi)教務(wù)系統(tǒng)首頁(yè),并打開(kāi)瀏覽器開(kāi)發(fā)者工具記錄瀏覽過(guò)程,然后正常登錄并瀏覽自己的課表,成績(jī)等信息。
2).下載jar包,將jar引用到自己需要的項(xiàng)目中,可創(chuàng)建一個(gè)新的工具類。
3).創(chuàng)建HttpClient實(shí)例,接著創(chuàng)建HttpRequestBase實(shí)例,接著調(diào)用HttpClient.execute()的方法獲取HttpResponse實(shí)例。得到驗(yàn)證碼圖片及其他數(shù)據(jù)。
測(cè)試代碼:
public class LoginUtil { // 教務(wù)系統(tǒng)首頁(yè) private String mainUrl = "http://202.115.80.153/"; // 驗(yàn)證碼獲取頁(yè)面 private String checkCodeUrl = "http://202.115.80.153/CheckCode.aspx"; // 驗(yàn)證碼圖片保存路徑 private String checkCodeDes = "C:\\Users\\linYang\\Desktop"; // 登陸頁(yè)面 private String loginUrl = "http://202.115.80.153/default2.aspx"; // 進(jìn)入教務(wù)系統(tǒng)首頁(yè)獲取的Cookie private String cookie = ""; // 學(xué)生學(xué)號(hào) private String stuNo = "201210411122"; // 教務(wù)系統(tǒng)密碼,為保護(hù)隱私,現(xiàn)將密碼隱藏 private String password = "******"; // 教務(wù)系統(tǒng)對(duì)應(yīng)的學(xué)生姓名 private String realName = ""; // 登錄成功后,重定向的頁(yè)面 private String contentUrl = "http://202.115.80.153/xs_main.aspx?xh=" + stuNo; // 獲取課程的頁(yè)面 private String courseUrl = "http://202.115.80.153/xskbcx.aspx?xh=" + stuNo; // 課程編號(hào) private String courseNo = "gnmkdm=N121603"; // 成績(jī)編號(hào) private String soureNo = ""; // HttpClient對(duì)象 private HttpClient httpClient = null; public void scanMainUrl() throws Exception { httpClient = HttpClients.createDefault(); //根據(jù)瀏覽器個(gè)記錄,是GET方法就使用HttpGet,是POST就是用HttpPost HttpGet getMainUrl = new HttpGet(mainUrl); //通過(guò)調(diào)用HttpClient的execute(HttpRequestBase)方法獲得HttpResponse實(shí)例 HttpResponse response = httpClient.execute(getMainUrl); //獲取Cookie cookie = response.getFirstHeader("Set-Cookie").getValue(); //輸出Cookie的值到控制臺(tái) System.out.println(cookie); //將HTML網(wǎng)頁(yè)解析成String,方便獲取Form中隱藏的參數(shù)以及需要的元素的信息 String tempHtml = parseToString(response); //構(gòu)造需要查詢?cè)氐募? ListkeyWords = new ArrayList (); //添加查詢?cè)匦畔?,這里新定義了一個(gè)實(shí)例類 keyWords.add(new QueryEntity("input[name=__VIEWSTATE]", "val", null)); //獲取查詢信息集合 List values = getValuesByKeyWords(tempHtml, keyWords); //獲取驗(yàn)證碼圖片 getMainUrl = new HttpGet(checkCodeUrl); response = httpClient.execute(getMainUrl); //將驗(yàn)證碼請(qǐng)求返回流解析成圖片保存到桌面,開(kāi)發(fā)人員也可根據(jù)需要可申請(qǐng)API直接編程獲取驗(yàn)證碼字符串 parseIsToImage(response.getEntity().getContent()); //調(diào)用登錄方法進(jìn)行登錄操作 login(values, httpClient, response); } public void login(List values, HttpClient httpClient, HttpResponse response) throws Exception { System.out.println("請(qǐng)輸入驗(yàn)證碼:"); //掃描輸入獲的驗(yàn)證碼 Scanner scanner = new Scanner(System.in); String checkCode = scanner.nextLine(); //創(chuàng)建一個(gè)HttpPost實(shí)例,進(jìn)行模擬登錄操作 HttpPost httpPost = new HttpPost(loginUrl); //設(shè)置HttpPost的頭信息 httpPost.addHeader("Cookie", cookie); httpPost.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,p_w_picpath/webp,*/*;q=0.8"); httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded"); httpPost.addHeader("Referer", mainUrl); List requestEntity = new ArrayList (); requestEntity.add(new BasicNameValuePair("__VIEWSTATE", values.get(0))); requestEntity.add(new BasicNameValuePair("txtUserName", stuNo)); requestEntity.add(new BasicNameValuePair("TextBox2", password)); requestEntity.add(new BasicNameValuePair("txtSecretCode", checkCode)); requestEntity.add(new BasicNameValuePair("RadioButtonList1", "%D1%A7%C9%FA")); requestEntity.add(new BasicNameValuePair("Button1", "")); requestEntity.add(new BasicNameValuePair("lbLanguage", "")); requestEntity.add(new BasicNameValuePair("hidPdrs", "")); requestEntity.add(new BasicNameValuePair("hidsc", "")); //設(shè)置httpPost請(qǐng)求體 httpPost.setEntity(new UrlEncodedFormEntity(requestEntity, "gb2312")); response = httpClient.execute(httpPost); judgeLoginSuccess(response); } /* 判斷是否登錄成功 */ private void judgeLoginSuccess(HttpResponse response) throws Exception { // TODO Auto-generated method stub //判斷網(wǎng)頁(yè)是否重定向,不能重定向,則需要檢查參數(shù)是否遺漏,密碼是否錯(cuò)誤! if (response.getStatusLine().getStatusCode() == 302) { System.out.println("登錄成功!!"); HttpGet getContent = new HttpGet(contentUrl); getContent.setHeader("Referer", mainUrl); getContent.setHeader("Cookie", cookie); response = httpClient.execute(getContent); String tempHtml = parseToString(response); System.out.println(tempHtml); List keyWords = new ArrayList (); keyWords.add(new QueryEntity("span#xhxm", "text", null)); //獲取學(xué)生姓名 realName = getValuesByKeyWords(tempHtml, keyWords).get(0); getCourse(); } else { System.out.println("登錄失敗?。?); } } /* 獲取課程頁(yè)面 */ public void getCourse() throws Exception { String courseUrl1 = courseUrl + "&xm=" + realName + "&" + courseNo; HttpGet getCourse = new HttpGet(courseUrl1); getCourse.setHeader("Referer", "http://202.115.80.153/xs_main.aspx?xh=201210411122"); getCourse.setHeader("Cookie", cookie); HttpResponse response = httpClient.execute(getCourse); String temp = parseToString(response); System.out.println("\n課程頁(yè)面:" + temp); } public static void main(String[] args) throws Exception { new LoginUtil().scanMainUrl(); } //將InputStream解析成圖片 public void parseIsToImage(InputStream is) throws Exception { FileOutputStream fos = new FileOutputStream(new File(checkCodeDes, "CheckCode.gif")); byte[] tempData = new byte[1024]; int len = 0; while ((len = is.read(tempData)) != -1) { fos.write(tempData, 0, len); } fos.close(); is.close(); } //將HttpResponse解析成String public String parseToString(HttpResponse response) throws Exception { InputStream is = response.getEntity().getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String line = null; StringBuilder builder = new StringBuilder(); while ((line = reader.readLine()) != null) { builder.append(line + "\n"); } reader.close(); is.close(); return builder.toString(); } //傳入查詢集合,獲取需要查詢?cè)氐闹担褂胘ava反射進(jìn)行封裝,簡(jiǎn)化操作 public List getValuesByKeyWords(String html, List queryEntities) throws Exception { List values = new ArrayList (); Element body = Jsoup.parse(html).select("body").get(0); for (QueryEntity entity : queryEntities) { Element element = body.select(entity.targetSelector).get(0); Method method = null; String value = null; Class> clazz = element.getClass(); if (entity.methodParms == null) { method = clazz.getMethod(entity.methodName); value = (String) method.invoke(element, new Object[] {}); } else { method = clazz.getMethod(entity.methodName, new Class[] { String.class }); value = (String) method.invoke(element, new Object[] { entity.methodParms }); } //輸出選擇器和對(duì)應(yīng)選擇器的值到控制臺(tái) System.out.println(entity.targetSelector + "\t" + value); values.add(value); } return values; } } //定義查詢html元素的查詢體實(shí)體類,目的在于簡(jiǎn)化查詢操作 class QueryEntity { String targetSelector; String methodName; String methodParms; /** * @param targetSelector 選擇器 * @param methodName 獲取值的方法名 * @param methodParms 方法回調(diào)參數(shù) */ public QueryEntity(String targetSelector, String methodName, String methodParms){ this.targetSelector = targetSelector; this.methodName = methodName; this.methodParms = methodParms; } }