HttpClient+Jsoup模擬登陸賀州學院教務系統,獲取學生個人信息


前言

  注:可能學校的教務系統已經做了升級,當前的程序不知道還能不能成功獲取信息,加上已經畢業,我的賬戶已經被注銷,試不了,在這里做下思路跟過程的記錄。

  在我的畢業設計中”基於SSM框架賀州學院校園二手交易平台設計與實現”我有這樣一個設想:使用學校教務系統賬號進行賀州學院學生身份認證(通過HttpClient模擬登陸),發布者身份信息真實、平台由學生(可以跟計算機協會合作,由他們進行維護)維護,平台安全可靠,校園身份認證時本校園二手交易平台的一大特色。為了實現這個功能,我對我們學校的教務系統進行了模擬登陸。

  我通過HttpClients模擬登陸教務系統,獲取學生信息,使用jsoup俗稱“大殺器”進行解析響應回來的html  匹配個人信息a標簽地址並做攜帶參數頁Referer進行第二次請求,使用jsoup來解析響應回來的htm匹配所有學生信息獲取我們想要的學生信息。在存儲過程中要進行唯一性認證,一個賬號只能認證一次,一個學生教務教務系統賬號只能綁定一個平台賬號。

  目前頭像的上傳我是這樣做的,先把圖片下載的用戶電腦本地作為臨時文件,再調用FtpUtil.upload()方法讀取文件上傳到我們nginx圖片服務器,成功上傳后刪除用戶電腦中的臨時文件。(因為上傳需要傳入一個InputStream但是在寫代碼過程中發現從響應回來的HttpResponse獲取到的數據轉為InputStream時文件出現損失導致上傳后圖片無法正常打開的情況)。而一個重要的技術點就是驗證碼的問題,在編寫代碼時發現想使用Tesseract-OCR開源工具,然而,實現起來沒那么簡單,所以我的做法是把教務系統的驗證碼直接writeTo到用戶的HttpServletResponse獲取圖片驗證碼,直接響應回瀏覽器,讓用戶自己手動輸入再傳到后台。

 

代碼編寫

引入jar:(如果想在控制台打印更多連接時的信息,可以使用log4j),或者使用maven引入也行

public class AuthenticationUtil {
    private static HttpClient client = HttpClients.createDefault();//實例化httpclient  
    //static HttpResponse response = null;  
    private static String rawHtml; //響應回來的數據
    
/*    public static void main(String[] args) throws Exception {
        //模擬登陸教務系統,獲取學生信息
        System.out.println("======模擬登陸教務系統,獲取學生信息======");
        //獲取驗證碼  
        int i=getVerifyingCode();  
        if(i==1){
            //提醒用戶並輸入驗證碼  
            System.out.println("驗證碼圖片下載成功! D:/verifyCode.gif,請輸入圖片驗證碼:");  
            String code;  
            Scanner in = new Scanner(System.in);  
            code = in.nextLine();  
            in.close();  
            Map map = login("xxx","***",code);
            if("200".equals(map.get("code"))){
                String xm=  (String) map.get("xm");//姓名
                String xh=  (String) map.get("xh");//學號
                String lbl_xb=  (String) map.get("lbl_xb");//性別
                String lbl_csrq=  (String) map.get("lbl_csrq");//出生日期
                String lbl_sfzh=  (String) map.get("lbl_sfzh");//身份證號
                String lbl_xy=  (String) map.get("lbl_xy");//學院
                String lbl_zymc=  (String) map.get("lbl_zymc");//專業
                String lbl_xzb=  (String) map.get("lbl_xzb");//班級
                System.out.println(xm);
            }else{
                System.out.println(map.get("msg"));
            }
        }else{
            System.out.println("驗證碼圖片下載失敗...");
        }
    }*/
    /**
     * 模擬登陸
     * @param login_xh
     * @param login_mm
     * @param code
     * @throws IOException 
     * @throws ParseException 
     */
    public static Map<String,String> login(String login_xh,String login_mm,String code) throws Exception {  
            Map<String,String> map =new HashMap<String,String>();
            String __VIEWSTATE="";
            HttpGet getVerifyCode = new HttpGet("http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/default2.aspx");  
            HttpResponse response = client.execute(getVerifyCode);//獲取驗證碼  
            rawHtml = EntityUtils.toString(response.getEntity(), "utf-8");
            Document doc = Jsoup.parse(rawHtml);
            Elements select_input = doc.select("input");
            for (Element a : select_input) {
                String name = a.attr("name");
                if("__VIEWSTATE".equals(name)){
                    __VIEWSTATE=a.attr("value");
                    break;
                }
            }
            
            //設定post參數
            ArrayList<NameValuePair> postData = new ArrayList<NameValuePair>();  
            postData.add(new BasicNameValuePair("Button1", ""));  
            postData.add(new BasicNameValuePair("RadioButtonList1", "學生"));//登陸賬號類型  
            postData.add(new BasicNameValuePair("TextBox2", login_mm));//密碼    
            postData.add(new BasicNameValuePair("Textbox1", ""));  
            postData.add(new BasicNameValuePair("__VIEWSTATE", __VIEWSTATE));  
            postData.add(new BasicNameValuePair("hidPdrs", ""));  
            postData.add(new BasicNameValuePair("hidsc", ""));
            postData.add(new BasicNameValuePair("lbLanguage", ""));
            postData.add(new BasicNameValuePair("txtSecretCode", code));//驗證碼  
            postData.add(new BasicNameValuePair("txtUserName", login_xh));//學號    
            //登錄 post請求  
            HttpPost post = new HttpPost("http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/default2.aspx");//構建post對象  
            post.setEntity(new UrlEncodedFormEntity(postData));//捆綁參數 
            post.setHeader("Accept", "text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8");//帶上參數頁
            post.setHeader("Cookie", "safedog-flow-item=");//帶上參數頁
            post.setHeader("Connection", "keep-alive");//帶上參數頁
            post.setHeader("Content-Type", "application/x-www-form-urlencoded");//帶上參數頁
            post.setHeader("Host", "jwxt.hzu.gx.cn");//帶上參數頁
            post.setHeader("Origin", "http://jwxt.hzu.gx.cn");//帶上參數頁
            post.setHeader("Upgrade-Insecure-Requests", "1");//帶上參數頁
            post.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36");//帶上參數頁
            post.setHeader("Referer", "http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/default2.aspx");//帶上referer 參數頁
            response = client.execute(post);//執行登陸行為  
            //登錄成功,發生302重定向
            if(302==response.getStatusLine().getStatusCode()){
                //把響應結果打印出來
                System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
                Header header = response.getFirstHeader("location"); // 跳轉的目標地址是在 HTTP-HEAD 中的
                String newuri = header.getValue(); // 這就是跳轉后的地址,再向這個地址發出新申請,以便得到跳轉后的信息是啥。
                newuri="http://jwxt.hzu.gx.cn/"+newuri;
//                System.out.println(newuri);
                //登錄成功  get請求
                HttpGet get=new HttpGet(newuri);
                get.setHeader("Cookie", "safedog-flow-item=");//帶上參數頁
                get.setHeader("Host", "jwxt.hzu.gx.cn");//帶上參數頁
                get.setHeader("Referer", "http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/default2.aspx");//帶上referer 參數頁
//                client.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 2000);
//                client.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000);
                // 超時設置
                RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();//設置請求和傳輸超時時間
                get.setConfig(requestConfig);
                /*
                 * 第二次身份認證時,程序會卡在這里
                 * 
                 */
                response = (CloseableHttpResponse) client.execute(get);//執行重定向 
                //打印輸出
//                rawHtml = EntityUtils.toString(response.getEntity(), "utf-8");  
//                System.out.println(rawHtml);
                String xsgrxxUrl="http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/";//個人信息a標簽地址
                if(200==response.getStatusLine().getStatusCode()){
                    //使用jsoup來解析響應回來的html  匹配個人信息a標簽地址
                    rawHtml = EntityUtils.toString(response.getEntity(), "utf-8");
                    Document document = Jsoup.parse(rawHtml);
                    Elements select_a = document.select("a");
                    for (Element a : select_a) {
                        String href = a.attr("href");
                        if(href.indexOf("xsgrxx.aspx")!=-1){
                            xsgrxxUrl=xsgrxxUrl+href;
                            break;
                        }
                    }
                    //查看個人信息   get請求
                    get=new HttpGet(xsgrxxUrl);
                    post.setHeader("Cookie", "safedog-flow-item=");//帶上參數頁
                    post.setHeader("Host", "jwxt.hzu.gx.cn");//帶上參數頁
                    get.setHeader("Referer", newuri);//帶上referer 參數頁
                    response = (CloseableHttpResponse) client.execute(get);//執行
                }
                rawHtml = EntityUtils.toString(response.getEntity(), "utf-8");  
                //打印輸出
//                System.out.println(rawHtml);
                //使用jsoup來解析響應回來的html    匹配所有學生信息
                Document document = Jsoup.parse(rawHtml);
                Elements select_span = document.select("span");
                for (Element span : select_span) {
                    String id = span.attr("id");
                    if("xh".equals(id)){//學號
                        String xh = span.text();
                        map.put("xh", xh);
//                        System.out.println("學號:"+xh);
                    }
                    if("xm".equals(id)){//姓名
                        String xm = span.text();
                        map.put("xm", xm);
//                        System.out.println("姓名:"+xm);
                    }
//                    if("lbl_TELNUMBER".equals(id)){//手機號碼
//                        String lbl_TELNUMBER = span.text();
//                        System.out.println("手機號碼:"+lbl_TELNUMBER);
//                    }
                    if("lbl_xb".equals(id)){//性別
                        String lbl_xb = span.text();
                        map.put("lbl_xb", lbl_xb);
//                        System.out.println("性別:"+lbl_xb);
                    }
                    if("lbl_csrq".equals(id)){//出生日期
                        String lbl_csrq = span.text();
                        map.put("lbl_csrq", lbl_csrq);
//                        System.out.println("出生日期:"+lbl_csrq);
                    }
                    if("lbl_byzx".equals(id)){//畢業中學
                        String lbl_byzx = span.text();
                        map.put("lbl_byzx", lbl_byzx);
//                        System.out.println("畢業中學:"+lbl_byzx);
                    }
                    if("lbl_mz".equals(id)){//民族
                        String lbl_mz = span.text();
                        map.put("lbl_mz", lbl_mz);
//                        System.out.println("民族:"+lbl_mz);
                    }
                    if("lbl_sfzh".equals(id)){//身份證號
                        String lbl_sfzh = span.text();
                        map.put("lbl_sfzh", lbl_sfzh);
//                        System.out.println("身份證號:"+lbl_sfzh);
                    }
                    if("lbl_xy".equals(id)){//學院
                        String lbl_xy = span.text();
                        map.put("lbl_xy", lbl_xy);
//                        System.out.println("學院:"+lbl_xy);
                    }
                    if("lbl_zymc".equals(id)){//專業
                        String lbl_zymc = span.text();
                        map.put("lbl_zymc", lbl_zymc);
//                        System.out.println("專業:"+lbl_zymc);
                    }
                    if("lbl_xzb".equals(id)){//班級
                        String lbl_xzb = span.text();
                        map.put("lbl_xzb", lbl_xzb);
//                        System.out.println("班級:"+lbl_xzb);
                    }
                    if("lbl_lys".equals(id)){//所在省份
                        String lbl_lys = span.text();
                        map.put("lbl_lys", lbl_lys);
//                        System.out.println("所在省份:"+lbl_lys);
                    }
                    if("jtdz".equals(id)){//家庭住址
                        String jtdz = span.text();
                        map.put("jtdz", jtdz);
//                        System.out.println("家庭住址:"+jtdz);
                    }
                }
                //上傳頭像到圖片服務器上
                Elements select_img = document.select("img");
                String imagUrl = select_img.attr("src");
                
                getPortrait((String)map.get("xh"),"http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/"+imagUrl, xsgrxxUrl);
                //ftp上傳到圖片服務器
                FileInputStream fileInputStream = new FileInputStream(new File("D:/portrait.jpg"));
                CpshResult result = FtpUtil.upload((String)map.get("xh")+"_portrait.jpg", fileInputStream);
                if(result.getStatus()==200){
                    map.put("tx", result.getData()+"");
                    //把文件刪掉
                    File file = new File("D:/portrait.jpg");
                    file.delete();
                }else{
                    System.out.println("頭像上傳失敗!");
                }
                //成功
                map.put("code", "200");
                map.put("msg", "驗證成功");
            }else if(200==response.getStatusLine().getStatusCode()){//響應狀態200,登錄失敗
                //使用jsoup來解析響應回來的html   解析彈窗提示信息
                rawHtml = EntityUtils.toString(response.getEntity(), "utf-8");
                Document document = Jsoup.parse(rawHtml);
                Elements select_script = document.select("script");
                String msg="";
                for (Element script : select_script) {
                    String html = script.html();
                    if(html.indexOf("alert")!=-1){
                        //只保留中文漢字
                        msg=html.replaceAll("[^\u4E00-\u9FA5]", "");
                        break;
                    }
                }
                //成功
                map.put("code", "400");
                map.put("msg", msg);
//                System.out.println(msg);
            }else if(500==response.getStatusLine().getStatusCode()){//
                map.put("code", "500");
                map.put("msg", "教務系統響應500...");
                
            }
//            client.getConnectionManager().shutdown();
//            response.close();
            return map;
    }
    /**
     * 獲取圖片驗證碼,直接響應回瀏覽器
     * @param client
     * @return
     */
    public static void getVerifyingCode(HttpServletResponse response1){
        try {  
            HttpGet getVerifyCode = new HttpGet("http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/CheckCode.aspx");//驗證碼get  
            HttpResponse response = client.execute(getVerifyCode);//獲取驗證碼  
            if(200==response.getStatusLine().getStatusCode()){//200響應碼
                //將響應回來的圖片信息writeTo 到 fileOutputStream
                response.getEntity().writeTo(response1.getOutputStream());
            }
        } catch (Exception e) {  
            e.printStackTrace();  
//            return 0;
        }finally {  
        }
    }
    /**
     * 獲取圖片驗證碼,下載到本地
     * @param client
     * @return
     */
    public static int getVerifyingCode(){
        FileOutputStream fileOutputStream = null;  
        try {  
//            HttpClient client = HttpClients.createDefault();//實例化httpclient  
            HttpGet getVerifyCode = new HttpGet("http://jwxt.hzu.gx.cn/(ffxibsu12r31de551s3q4w3o)/CheckCode.aspx");//驗證碼get  
            HttpResponse response;  
            response = client.execute(getVerifyCode);//獲取驗證碼  
            if(200==response.getStatusLine().getStatusCode()){//200響應碼
                /*驗證碼寫入文件,保存為verifyCode.jped*/  
                fileOutputStream = new FileOutputStream(new File("D:/verifyCode.gif"));  
                //將響應回來的圖片信息writeTo 到 fileOutputStream
                response.getEntity().writeTo(fileOutputStream);
                return 1;
            }else{
                return 0;
            }
        } catch (Exception e) {  
            e.printStackTrace();  
            return 0;
        }finally {  
            try {  
                fileOutputStream.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }
    }
    /**
     * 下載頭像圖片
     * @param cilent
     * @param imagUrl
     * @param referer
     * @return
     */
    public static void getPortrait(String xh,String imagUrl,String referer){
//        HttpClient client = HttpClients.createDefault();//實例化httpclient  
        FileOutputStream fileOutputStream=null;
        try {  
//            HttpClient client = HttpClients.createDefault();//實例化httpclient  
            HttpGet portrait = new HttpGet(imagUrl);//get請求  頭像照片
            //portrait.setHeader("Referer",referer);
            HttpResponse response = client.execute(portrait);//  執行
            if(200==response.getStatusLine().getStatusCode()){//200響應碼
//                /*圖片寫入文件,保存為portrait.jpg*/  
                File file = new File("D:/portrait.jpg");
                file.createNewFile();
                fileOutputStream = new FileOutputStream(file);  
                response.getEntity().writeTo(fileOutputStream);
                
            }
        } catch (Exception e) {  
            e.printStackTrace();  
        }finally {  
            try {
                fileOutputStream.flush();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

效果

可以再控制台打印出來,我這里是作為layer彈窗:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM