课程格子和超级课程表这两个应用,想必大学生都很熟悉,使用自己的学号和教务系统的密码,就可以将自己的课表导入,随时随地都可以在手机上查看。

  其实稍微了解一点php的话,我们也可以做一个类似这样的web 应用。

  1,解决掉验证码

    其实这是正方的一个小bug,当我们进入登陆界面时,浏览器会去请求服务器,服务器会生成一个验证码图片。如果我们不去请求这个图片,那么正方后台也不会生成相应的        验证码,于是这样我们就有了可乘之机,让我高兴会儿~这时,我们在不填写验证码的情况下,可以很流畅的进入。大家可以在自己的电脑上禁止访问验证码的地址,然后试试这        是不是真的~当然,这只对正方有效。

  2,php 的curl 模拟登陆

    这里直接贴一个脚本之家对 curl 的讲解吧 http://www.jb51.net/article/51299.htm

    接下来就是相关代码了,相信很多人和我一样,只喜欢看例子,对于长篇大论的讲解,转头就走……不过这个习惯还是不好……废话不多说!

    

//模拟登陆
function curl_request($url,$post='',$cookie='', $returnCookie=0){
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)');
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
curl_setopt($curl, CURLOPT_REFERER, "这里一定要换成教务系统登陆的url"); //填写教务系统url
if($post) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
}
if($cookie) {
curl_setopt($curl, CURLOPT_COOKIE, $cookie);
}
curl_setopt($curl, CURLOPT_HEADER, $returnCookie);
curl_setopt($curl, CURLOPT_TIMEOUT, 20);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($curl);
if (curl_errno($curl)) {
return curl_error($curl);
}
curl_close($curl);
if($returnCookie){
list($header, $body) = explode("\r\n\r\n", $data, 2);
preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches);
$info['cookie'] = substr($matches[1][0], 1);
$info['content'] = $body;
return $info;
}else{
return $data;
}
}

  3,教务系统登陆页面的隐藏字段

    举个栗子

    

    <input type="hidden" name="__VIEWSTATE" value="dDwyODE2NTM0OTg7Oz61eIbnKVojBioGYtg2vsy2SklwiA==">

    这些东西在登陆的时候也是需要带上的,顺便贴出函数,顺便暴漏了博主的学校……皇家种地大学(主要是正则表达式的运用)

    

    
  //登陆页面的隐藏字段
  function getView(){
$url = 'http://jw.hzau.edu.cn/default2.aspx';
$result = curl_request($url);
$pattern = '/<input type="hidden" name="__VIEWSTATE" value="(.*?)" \/>/is';
preg_match_all($pattern, $result, $matches);
$res[0] = $matches[1][0]; return $res[0] ;
}

  //返回教室查询页面的隐藏值
  private function getViewJs($cookie,$xh){
    $url = "http://jw.hzau.edu.cn/xxjsjy.aspx?xh={$xh}";
    $result = curl_request($url,'',$cookie);
    $pattern = '/<input type="hidden" name="__VIEWSTATE" value="(.*?)" \/>/is';
    preg_match_all($pattern, $result, $matches);
    $res[0] = $matches[1][0];
    return $res[0] ;
  }

  4,cookie 的获取

    

function login($xh,$pwd){
$url = 'http://jw.hzau.edu.cn/default2.aspx';
$post['__VIEWSTATE'] = $this->getView();
$post['txtUserName'] = $xh; //填写学号
$post['TextBox2'] = $pwd; //填写密码
$post['txtSecretCode'] = '';
$post['lbLanguage'] = '';
$post['hidPdrs'] = '';
$post['hidsc'] = '';
$post['RadioButtonList1'] = iconv('utf-8', 'gb2312', '学生');
$post['Button1'] = iconv('utf-8', 'gb2312', '登录');
$result = curl_request($url,$post,'', 1);
return $result['cookie'];
}

  5,让我们来试试查课表的功能,格式有点乱额,大家凑合着看,我把课表转成了一个二维关联数组

    

//返回课表字符串
private function classresult($xh,$pwd){
date_default_timezone_set("PRC"); //时区设置
$classList = "";//声明课表变量 $cookie = $this->login($xh,$pwd);
$view = $this->getViewJs($cookie,$xh);//验证密码是否正确 //如果密码正确
if (!empty($view)) {
$url = "http://jw.hzau.edu.cn/xskbcx.aspx?xh={$xh}";
$result = curl_request($url,'',$cookie); //保存的cookies
preg_match_all('/<table id="Table1"[\w\W]*?>([\w\W]*?)<\/table>/',$result,$out);
$table = $out[0][0]; //获取整个课表 preg_match_all('/<td [\w\W]*?>([\w\W]*?)<\/td>/',$table,$out);
$td = $out[1];
$length = count($td); //获得课程列表
for ($i=0; $i < $length; $i++) {
$td[$i] = str_replace("<br>", "", $td[$i]); $reg = "/{(.*)}/"; if (!preg_match_all($reg, $td[$i], $matches)) {
unset($td[$i]);
}
} $td = array_values($td); //将课程列表数组重新索引
$tdLength = count($td);
for ($i=0; $i < $tdLength; $i++) {
$td[$i] = iconv('GB2312','UTF-8',$td[$i]);
} //将课表转换成数组形式
function converttoTable($table){
$list = array(
'sun' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'mon' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'tues' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'wed' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'thur' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'fri' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
),
'sat' => array(
'1,2' => '',
'3,4' => '',
'5,6' => '',
'7,8' => '',
'9,10' => ''
)
);
$week = array("sun"=>"周日","mon"=>"周一","tues"=>"周二","wed"=>"周三","thur"=>"周四","fri"=>"周五","sat"=>"周六");
$order = array('1,2','3,4','5,6','7,8','9,10');
foreach ($table as $key => $value) {
$class = $value;
foreach ($week as $key => $weekDay) {
$pos = strpos($class,$weekDay);
// echo $pos;
if ($pos) {
$weekArrayDay = $key; //获取list数组中的第一维key
foreach ($order as $key => $orderClass) {
$pos = strpos($class,$orderClass);
if ($pos) {
$weekArrayOrder = $orderClass; //获取该课程是第几节
break;
}
}
break;
}
}
$list[$weekArrayDay][$weekArrayOrder] = $class;
}
return $list;
} //调用函数
return converttoTable($td);
}else{
return 0;
}
}

  6,再试试查询空教室的功能

    

//空教室查询结果
public function roomresult(){
$xh = ""; //设置学号
$pwd = ""; //学号对应的密码 $cookie = $this->login($xh,$pwd);
$url = "http://jw.hzau.edu.cn/xs_main.aspx?xh={$xh}";
$result = curl_request($url,'',$cookie); //保存的cookies $url="http://jw.hzau.edu.cn/xxjsjy.aspx?xh={$xh}";
$post['Button2'] = iconv('utf-8', 'gb2312', '空教室查询');
$post['__EVENTARGUMENT']='';
$post['__EVENTTARGET']='';
$post['__VIEWSTATE'] = $this->getViewJs($cookie,$xh);
$post['ddlDsz'] = iconv('utf-8', 'gb2312', '单');
$post['ddlSyXn'] = '2014-2015'; //学年
$post['ddlSyxq'] = '1';
$post['jslb'] = '';
$post['xiaoq'] = ''; $post['kssj']=$_GET['start']; //提交的开始查询时间
$post['sjd']=$_GET['class'];//提交的课程节次 $post['xn']='2014-2015';//所在学年
$post['xq']='2';//所在学期
$post['xqj']='6';//当天星期几
$post['dpDataGrid1:txtPageSize']=90;//每页显示条数 $result = curl_request($url,$post,$cookie,0); preg_match_all('/<span[^>]+>[^>]+span>/',$result,$out);
$tip = iconv('gb2312', 'utf-8', $out[0][3]);//获取页面前部的提示内容
preg_match_all('/<table[\w\W]*?>([\w\W]*?)<\/table>/',$result,$out);
$table = iconv('gb2312', 'utf-8', $out[0][0]); //获取查询列表 $this->load->view("classroom",array('tip'=>$tip,'table'=>$table));
}

  总结起来就是这些了,每个学校的教务系统都不尽相同,这时我们可以借助火狐浏览器的 firebug 抓包,看看到底提交了哪些东西。如果不成功,要看看自己该提交的东西post 上去了没有,如果再不成功,额……结合网上另外一些博文,也许可以找到答案。

  就这些了,赶快去试试吧!

以正方教务系统为例,用php模拟登陆抓取课表、空教室的更多相关文章

  1. JavaScript之正方教务系统自动化教评[插件-转载]

    [声明]本插件系学院学长原创,非博主所创,发布此处,仅供学习和效仿. /** * @name:正方教务系统自动化教评-插件 * * @author:chenzhongshu * @date:2017- ...

  2. 广州商学院Python正方教务系统爬虫(获取个人信息成绩课表修改密码)

    使用python的requests库简单爬取,使用xpath解析内容 可以获取个人信息.个人照片.成绩单和课表 github地址:https://github.com/PythonerKK/GZCC- ...

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

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

  4. 课程助理For Windows(预览版,正方教务系统学生查分工具)

    其实盖子已经开发了一个功能更强大的版本,但是那个版本依然基于正方系统,也就是说只要正方系统跪了或者张院士在网站上做点手脚,这个小工具就会失效. 今天给大家的版本虽然功能及其简单.界面极端丑陋,但是通过 ...

  5. 高版本正方教务系统上传后缀过滤不严导致能直接上传Webshell

    在旧版本中有一个利用插件上传文件的漏洞,但是在新版本中已经没有了这个插件.这个漏洞是由于过滤不严造成的,可以直接上传Webshell进行提权,由于代码在DLL中,全国大部分高校均有此漏洞,影响范围很大 ...

  6. 正方教务系统客户端 error loading midas.dll.

    在windows xp/7/10上安装了客户端,安装到注册字体一步,没有响应,强行结束.启动客户端,登录,出现  error loading midas.dll. 32位:先将 midas.dll 放 ...

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

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

  8. 教你用python爬虫监控教务系统,查成绩快人一步!

    教你用python爬虫监控教务系统,查成绩快人一步!这几天考了大大小小几门课,教务系统又没有成绩通知功能,为了急切想知道自己挂了多少门,于是我写下这个脚本. 设计思路:设计思路很简单,首先对已有的成绩 ...

  9. Java模拟登录系统抓取内容【转载】

    没有看考勤的习惯,导致我的一天班白上了,都是钱啊,系统也不发个邮件通知下....     为了避免以后还有类似状况特别写了个java模拟登录抓取考勤内容的方法(部分代码来自网络),希望有人修改后也可以 ...

随机推荐

  1. ActionBar隐藏修改图标和标题

    有时候在一些子页面或者内容页面,不需要显示ActionBar的标题栏图标.可用如下方式进行设置. 首先获取到ActionBar对象 ActionBar actionBar=getActionBar() ...

  2. SQL Server数据库---》基础

    SQL Server:只是操作数据库的一个工具(这种工具,只是提供一个界面化的方式让用户方便操作数据库) 开启服务:点击:我的电脑(计算机)--管理--服务和应用程序--服务--开启SQL Serve ...

  3. Nutch2.3分布执行过程中Mongodb中数据的变化

    inject $ nutch inject /opt/nutch/runtime/local/urls/ > db.stats() { "db" : "nutch& ...

  4. Extjs springmvc session 超时 处理

    如果你的项目使用ExtJS作为表现层,你会发现,SESSION超时控制将是一个问题.本文将就自己的经验,来解决这一问题,当然,解决问题并非只有一种方法,我只是提出我的方法.首先,做超时控制,必需使用过 ...

  5. js对JSON数据排序

    一.适用于数字排序和字幕排序json 的排序方法有很多种,这是其中最简单的一种方法. 代码如下: var sortBy = function (filed, rev, primer) {    rev ...

  6. 理解C语言声明的优先级规则

    声明从它的名字开始读取,然后依次按优先级依次读取. 优先级从高到低依次是 声明中被括号括起来的那部分 后缀操作符: 括号()表示这是一个函数 方括号表[]这是一个数组 前缀操作符:星号*表示“指向.. ...

  7. C#版-百度网盘API的实现(二)

    在这篇文章中,我们通过代码来实现百度网盘的简单操作, 一,登陆,在代码中,我有一个Baidu1的类,实例化该类时回执行登陆方法,该类对外开放了三个方法, 1,GetFileDir获取根目录下的文件夹及 ...

  8. JBoss+Ant实现EJB无状态会话bean实例

    EJB分为session bean.entity bean.message-driven bean,session bean又分为无状态会话bean和有状态会话bean. session bean负责 ...

  9. 多个Activity之间的切换与数据交互

    总结 两个activity之间切换我概括的分为两步: 1. 代码实现切换操作.2.配置中声明另外一个acitivity! 1. 代码实现切换操作 显示定义一个intent 对象,Intent 这个类的 ...

  10. ORACLE 查找字段在哪些表里存在

    查找不是主键的字段在哪些表里存在: select owner, table_namefrom dba_tab_columnswhere lower(column_name)='firstname'; ...