新版正方教务系统请点这里:模拟登陆新版正方教务管理系统(获取学籍信息、课表和成绩)

最近想学点爬虫玩玩,拿学校的教务系统练练手。学校与很多高校一样,用的是正方教务管理系统,非常的不好用,经常出现登陆不上去、卡死的情况,主页如下图所示:

主页地址:http://222.24.62.120

模拟登录


1. 分析登录的URL和所需提供的数据

我们输入学号、密码和验证码登录后,点击登录。这时浏览器会向服务器提交一个POST请求:

我们由上图中的数据可知,登录请求的URL地址为:

http://222.24.62.120/default2.aspx

所提交的数据除了学号、密码、验证码、用户类型,还有其他的数据:

  • __VIEWSTATE在源码中可以找到,是一个隐藏域,猜测是用来做验证
<input type="hidden" name="__VIEWSTATE" value="dDwxNTMxMDk5Mzc0Ozs+lYSKnsl/mKGQ7CKkWFJpv0btUa8=" />
  • Textbox1是上次登陆的用户学号
  • RadioButtonList1通过看源码可知为%D1%A7%C9%FA,是”学生”经过URL编码(gb2312)后的字符串。
  • 后四个为空可以不用管

创建一个类:ConnectJWGL
属性如下:

    private String stuNum;private String stuName;private String __VIEWSTATE = "";private Map<String,String> cookies = new HashMap<>();private Connection connection;private Connection.Response response;private Document document;

2. 获取Cookies和__VIEWSTATE

给主页发一个请求,然后将响应的Cookies保存下来。并在其中提取__VIEWSTATE的值。

在ConnectJWGL类中添加一个connectIndex方法
代码如下:

    //接获取cookies和__VIEWSTATEpublic void connectIndex(){try{//获取连接connection = Jsoup.connect("http://222.24.62.120");connection.header("User-Agent",// 配置模拟浏览器"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");response = connection.timeout(3000).execute();//保存Cookiescookies = response.cookies();// 将响应转换为Dom树,以便获取__VIEWSTATEdocument = Jsoup.parse(response.body());for(Element element:document.getElementsByTag("input")) {if (element.attr("name").equals("__VIEWSTATE")) {__VIEWSTATE = element.val();break;}}}catch (IOException ex){ex.printStackTrace();}}

3. 取得验证码

在Chrome中定位验证码图片,代码如下

<img id="icode" title="看不清,换一张" onclick="reloadcode();" alt="看不清,换一张" src="CheckCode.aspx" border="0" style="POSITION: absolute; TOP: 5px; LEFT: 130px">

可以知道点击图片就会重新申请一个验证码,src为:

http://222.24.62.120/CheckCode.aspx

图片处理的方式有很多种,因为ORC图片识别成功概率低、机器学习学习难度比较大,所以采用把图片下载到本地再手动输入的方法,以后我倾向于自己写一个验证码识别工具。

在获取验证码的时候,要将Cookies上传,让服务器知道你的身份,要不然下载下来的图片没法用。

在ConnectJWGL类中添加一个downloadCheckcode方法
代码如下:

    //下载验证码到本地public void downloadCheckcode(){try{String captcha_url = "http://222.24.62.120/CheckCode.aspx";response = Jsoup.connect(captcha_url).cookies(cookies).ignoreContentType(true) // 获取图片需设置忽略内容类型.userAgent("Mozilla").method(Connection.Method.GET).timeout(3000).execute();byte[] bytes = response.bodyAsBytes();//在本地建立文件夹File file = new File("/home/limeng/Desktop/checkcode.aspx");if (file.exists()) {file.delete();}OutputStream output = new FileOutputStream(file);BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);bufferedOutput.write(bytes);bufferedOutput.close();output.close();}catch (IOException ex){ex.printStackTrace();}}

4. 登录

在ConnectJWGL类中添加一个login方法

    //登录public boolean login(String stuNum,String password,String checkCode){this.stuNum = stuNum;stuName = "";//填充post数据Map<String, String> datas = new HashMap<>();datas.put("__VIEWSTATE",__VIEWSTATE);datas.put("txtUserName",stuNum);datas.put("TextBox2",password);datas.put("txtSecretCode",checkCode);datas.put("RadioButtonList1","%D1%A7%C9%FA");datas.put("Button1","");datas.put("lbLanguage","");datas.put("hidPdrs","");datas.put("hidsc","");try{connection = Jsoup.connect("http://222.24.62.120/default2.aspx");connection.header("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");// 设置cookie和post上面的map数据response = connection.postDataCharset("GB2312").ignoreContentType(true).method(Connection.Method.POST).data(datas).cookies(cookies).execute();document = response.parse();if(document.title().equals("欢迎使用正方教务管理系统!请登录")){String error = document.getElementsByTag("script").get(1).data();Pattern pattern = Pattern.compile("(?<=alert\\(')[^']*");Matcher matcher = pattern.matcher(error);while(matcher.find()){System.out.print("登陆失败,");System.out.println(matcher.group());}return false;}else {stuName = document.getElementById("xhxm").text();stuName = stuName.substring(0,stuName.length()-2);System.out.println("登陆成功,欢迎你"+stuName+"!");return true;}}catch (IOException ex){ex.printStackTrace();return false;}}

登录成功会跳转到:

http://222.24.62.120/xs_main.aspx?xh=学号

否则转到登录界面,并提示错误信息。

获取学生个人信息


在登录成功后,我们点击信息维护中的(个人信息)。

这时会去以get方式请求:

http://222.24.62.120/xsgrxx.aspx

传递了三个参数:

  • xh:学号
  • xm:URL编码过的姓名
  • gnmkdm:N121501(应该是业务编号,请求课表就是N121603)

我们不知道学生的姓名,但是通过查看主界面,可以发现“欢迎您: ××同学”,简单处理一下即可。

Referer(很重要,要不然无法请求上面的连接

http://222.24.62.120/xs_main.aspx?xh=学号 

在ConnectJWGL类中添加一个getStudentInformation方法
代码如下:

    //获取学生个人信息public void getStudentInformation(){try{String infoURL = "http://222.24.62.120/xsgrxx.aspx?xh="+stuNum+"&xm="+URLEncoder.encode(stuName,"GB2312")+"&gnmkdm=N121501";connection = Jsoup.connect(infoURL);response = connection.ignoreContentType(true).method(Connection.Method.GET).userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0").referrer("http://222.24.62.120/xs_main.aspx?xh="+stuNum).cookies(cookies).postDataCharset("GB2312").timeout(3000).execute();document = response.parse();if(document.getElementById("lbxsgrxx_xb") != null){System.out.println("---基本信息---");System.out.println(document.getElementById("lbxsgrxx_xb").text()+document.getElementById("lbl_xb").text());System.out.println(document.getElementById("lbxsgrxx_csrq").text()+document.getElementById("lbl_csrq").text());System.out.println(document.getElementById("lbxsgrxx_xy").text()+document.getElementById("lbl_xy").text());System.out.println(document.getElementById("lbxsgrxx_dqszj").text()+document.getElementById("lbl_dqszj").text());System.out.println(document.getElementById("TDzymc").text()+document.getElementById("lbl_zymc").text());System.out.println(document.getElementById("lbxsgrxx_xzb").text()+document.getElementById("lbl_xzb").text());}else {System.out.println("获取信息失败");}}catch (IOException ex){ex.printStackTrace();}}

测试


Main.java

import java.util.Scanner;public class Main {public static void main(String[] args){String stuNum;String password;String checkCode;Scanner input = new Scanner(System.in);ConnectJWGL connectJWGL = new ConnectJWGL();connectJWGL.downloadCheckcode();System.out.print("请输入学号:");stuNum = input.next();System.out.print("请输入密码:");password = input.next();System.out.print("请输入验证码:");checkCode = input.next();if(connectJWGL.login(stuNum,password,checkCode)){connectJWGL.getStudentInformation();}input.close();}
}

完整代码点这里:爬取学校教务系统获取学生信息

要注意的细节

  1. 在获取Cookies后,以后的每一次请求都要把Cookies带上。
  2. Too many redirects occurred trying to load URL 表示进入重定向循环,不知道该跳转到哪一个界面。如果把自动跳转关闭就出现页面提示:Object moved to here.
    这个问题是在获取个人信息时出现的,由于在登录成功时不小心更新了一次Cookies,导致Cookies为空,请求时服务器不知道我的身份,修正后就可以正常获取信息了。
  3. 请求时要注意目标请求是否需要Referer。Referer告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理,有网页会限定请求的上一个地址。
参考

Jsoup Cookbook(中文版)
Java爬虫初识之模拟登录
Java爬虫教程:模拟用户表单登录

爬取正方教务管理系统获取学生信息相关推荐

  1. android之爬取正方教务管理系统获取信息

    一.问题 由于项目需要,要做一个课程表,所以需要获取学校中的课程表数据. 二.方法 模拟浏览器一样向服务器发送数据和获取数据 需要工具:抓包工具fiddler4和解析HTTP代码的Jsoup 三.代码 ...

  2. Java爬取正方教务,获取成绩信息

    github.superwuit.cn /**  * 2018-2-3 21:15:16  * @Description: 模拟登陆正方教务获取成绩HTML页面,并利用正则表达式提取成绩信息  * @ ...

  3. 爬取正方教务系统完成成绩查询

    刚刚开始接触爬虫,在爬过起点中文网这种不要登陆的网页后转向教务系统这种需要登陆的网页,登录这个因为还有验证码,刚接触所以花费了很长时间,说到底其实就是把你的信息交给网站让它可以认得你的过程,而登录过后 ...

  4. python爬虫登录正方教务管理系统获取成绩数据

    本程序以四川理工学院教务管理系统为例.... 准备工作:1.ruquests库的使用(或者urllib也可行) 2.正则表达式的书写 3.HTTP通信基础 4.一些解析库的使用 准备一个浏览器监视工具 ...

  5. python爬取学校教务管理系统

    写这个爬虫的缘由 以前用java写过一个爬取学校的教务系统的爬虫 https://blog.csdn.net/ygdxt/article/details/81158321,最近痴迷Python爬虫,了 ...

  6. python爬取学校教务管理系统_python requests模拟登陆正方教务管理系统,并爬取成绩...

    最近模拟带账号登陆,查看了一些他人的博客,发现正方教务已经更新了,所以只能自己探索了. 登陆: 通过抓包,发现需要提交的值 需要值lt,这是个啥,其实他在访问登陆页面时就产生了 session=req ...

  7. python爬取学校教务管理系统_python爬虫模拟登陆学校教务处

    最近在学python爬虫,我想教务处官网可能是每个学生第一个自己动手爬取的网站吧.而且很多学校的教务处没有验证码,很适合初学者练手. 环境准备 本次模拟登陆用到的库除了requests外还有lxml, ...

  8. 爬取正方教务系统课程表

    被一个学长布置下的任务-有些地方可能不够完整- 思路: 首先你需要完成登录操作: (1) 首先根据教务系统网站的审查元素, 发现了一个验证码的网址:http://210.40.2.253:8888/( ...

  9. 爬取foxconn传媒网获取电影信息

    #!/user/bin/env python # coding=utf-8 '''获取页面的所有电影名字及其对应的href,加下载链接用正则表达式取数据 '''import requests impo ...

最新文章

  1. 区分Java拦截器和过滤器
  2. PyCharm:选择内容多个光标解决办法
  3. Python基础(7)——for循环
  4. python3 分离路径 目录 文件名 后缀
  5. SectionIndexer中的getSectionForPosition()与getPositionForSection()
  6. 使用netty搭建一个简单的聊天室
  7. 关于以追加模式写入文件时,为什么第一行是空行?
  8. iOS-raywenderlich翻译-AFNetworking速成教程
  9. oracle+标记要,oracle ORA-00031:session marked for kill(标记要终止的会话)解决方法
  10. Codeforces 786B Legacy (线段树优化建图)
  11. java绘制半透明图片_如何使绘制的图像在Java中透明
  12. Linux 常用命令六 cp和mv
  13. PostgrSQL流复制wal异常
  14. android中多线程与ui,Android UI线程和非UI线程
  15. java图形界面_学习Java有什么用?Java的应用领域有哪些?
  16. linux下加载ISO镜像的方法
  17. 兄弟连新版PHP视频教程(共346讲)
  18. C语言递归函数 计算学生年龄
  19. Android 加固应用
  20. Office显示未授权,需要激活这种情况应该怎么处理

热门文章

  1. 组织的好坏取决于领导者的心
  2. 话费充值API接口源码文档
  3. win10滑动关机代码bat_win10滑动关机代码bat_win10设置自动关机和取消自动关机的bat命令...
  4. Excel数据透视表经典教程五《功能选项卡》
  5. 【集成学习系列教程5】LightGBM
  6. android开发自定义相机镜像问题
  7. 【学术会议】如何rebuttal学术论文?
  8. c 调用 linux驱动程序,Linux下的C编程实战(五)――驱动程序设计
  9. 怎样学好中医,非常值得一读
  10. 《途客圈创业记:不疯魔,不成活》一一1.5 依依辞别Juniper