前言

  注:可能学校的教务系统已经做了升级,当前的程序不知道还能不能成功获取信息,加上已经毕业,我的账户已经被注销,试不了,在这里做下思路跟过程的记录。

  在我的毕业设计中”基于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弹窗:

HttpClient+Jsoup模拟登陆贺州学院教务系统,获取学生个人信息的更多相关文章

  1. Jsoup模拟登陆例子

    Jsoup模拟登陆小例子,不同的网站,需要不同的模拟策略,散仙在这里仅仅作为一个引导学习. package com.jsouplogin; import java.util.HashMap; impo ...

  2. Java模拟登录带验证码的教务系统(原理详解)

    一:原理 客户端访问服务器,服务器通过Session对象记录会话,服务器可以指定一个唯一的session ID作为cookie来代表每个客户端,用来识别这个客户端接下来的请求. 我们通过Chrome浏 ...

  3. 基于SSM框架贺州学院校园二手交易平台设计与实现

    前言 这个是我当时的毕业论文,分享出来,给同学们参考. 绪论 随着中国新四大发明的诞生,网购成了千千万万网友们购物的新方式,新的购物方式促进商业的发展,但随着人们生活水平的提高,许多新购置的物品用了没 ...

  4. HttpClient + Jsoup模拟登录教务处并获取课表

    1.概述 最近想做一个校园助手类的APP,由于第一次做,所以打算先把每个功能单独实现,防止乱了阵脚.利用教务处登录获取课表和成绩等是一个基本功能,所以以获取课表为例实现了这个功能.完整代码点这里,尝试 ...

  5. 在Android上模拟登录广工正方教务系统查询成绩

    这是在博客园里开博以来写的第一篇博客. 因为之前看过很多人都有发过关于模拟登录正方软件获取数据的文章,自己觉得挺好玩的便也去动手一做,开始还以为挺难的,但实际做起来还蛮简单的,当然其中还有些小插曲. ...

  6. HttpURLConnection模拟登录学校的正方教务系统

    教务系统登录界面 如图1-1 1-1 F12-->network查看登录教务系统需要参数: __VIEWSTAT txtUserName TextBox2 txtSecretCode Radio ...

  7. 使用php的curl爬去青果教务系统 课表(转)

    1. 分析 首先我们要了解 Http Cookie 的作用(可参考HTTP cookies 详解),简单来说就是维持一个会话,这样我们就能在登陆一个网页后,就能进入这个网页需要登陆的界面. 现在我们需 ...

  8. 以正方教务系统为例,用php模拟登陆抓取课表、空教室

    课程格子和超级课程表这两个应用,想必大学生都很熟悉,使用自己的学号和教务系统的密码,就可以将自己的课表导入,随时随地都可以在手机上查看. 其实稍微了解一点php的话,我们也可以做一个类似这样的web ...

  9. php 的curl 模拟登陆

    做一个类似这样的web 应用. 1,解决掉验证码 其实这是正方的一个小bug,当我们进入登陆界面时,浏览器会去请求服务器,服务器会生成一个验证码图片.如果我们不去请求这个图片,那么正方后台也不会生成相 ...

随机推荐

  1. Go的Get命令兼容公司Gitlab仓库的HTTP协议

    对于公司的私有Gitlab仓库,没有对https支持,在使用最新版本的go get命令时,需要使用-insecure参数来支持http,但如果导入的包里边依赖了需要https的仓库,就不好使了,折腾了 ...

  2. TYVJ1424-占卜DIY

    题目有点长,对于样例最好拿张A4纸模拟写一遍. 可以发现程序一定不会死循环,因为每种牌都是4张,而死循环的条件是某种牌有5张然后你拿了又放进去.如果写出来死循环了,那就是写不对了. 有几点可能是需要注 ...

  3. JavaScript复习笔记——数据类型

    1.undefined 使用var声明但未对其进行初始化时,这个变量的值就是undefined. 对未被初始化的值使用typeof会返回undefined值,而对未声明的变量执行typeof操作同样也 ...

  4. 《Node.js高级编程》之Node 核心API基础

    Node 核心API基础 第三章 加载模块 第四章 应用缓冲区 第五章 事件发射器模式简化事件绑定 第六章 使用定时器制定函数执行计划 第三章 加载模块 本章提要 加载模块 创建模块 使用node_m ...

  5. arp脚本

    1.什么是arp?arp可以解决什么问题? ARP:是地址解析协议 arp解决我们知道一个机器(主机或者路由器)的IP地址,需要找出其相应的硬件地址 2.编写ARP脚本,抓取对应主机的mac地址 1 ...

  6. Asp.Net WebAPI核心对象解析(三)

    对于.NET的分布式应用开发,可以供我们选择的技术和框架比较多,例如webservice,.net remoting,MSMQ,WCF等等技术.对于这些技术很多人都不会陌生,即时没有深入的了解,但是肯 ...

  7. Visualizing the Git data model

    I wrote a small tool git-graph.py over the weekend which can be used to generate the object graph of ...

  8. 2017-12-04 编写Visual Studio Code插件初尝试

    参考官方入门: Your First Visual Studio Code Extension - Hello World 源码在: program-in-chinese/vscode_helloWo ...

  9. WEB站点服务器安全配置

    WEB站点服务器安全配置   本文转自:i春秋社区   // 概述 // 熟悉网站程序 // 更改默认设置的必要性 // 目录分析与权限设置技巧 // 防止攻击其他要素 // 公司官网不可忽视的安全性 ...

  10. Logistic回归Cost函数和J(θ)的推导----Andrew Ng【machine learning】公开课

    最近翻Peter Harrington的<机器学习实战>,看到Logistic回归那一章有点小的疑问. 作者在简单介绍Logistic回归的原理后,立即给出了梯度上升算法的code:从算法 ...