当前位置:首页 > PHP教程 > php应用 > 列表

php实现模拟登陆方正教务系统抓取课表

发布:smiling 来源: PHP粉丝网  添加日期:2021-05-27 10:36:26 浏览: 评论:0 

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

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

1,解决掉验证码

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

2,php 的curl 模拟登陆

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

  1. //模拟登陆 
  2.   function curl_request($url,$post='',$cookie=''$returnCookie=0){ 
  3.       $curl = curl_init(); 
  4.       curl_setopt($curl, CURLOPT_URL, $url); 
  5.       curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)'); 
  6.       curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); 
  7.       curl_setopt($curl, CURLOPT_AUTOREFERER, 1); 
  8.       curl_setopt($curl, CURLOPT_REFERER, "这里一定要换成教务系统登陆的url"); //填写教务系统url 
  9.       if($post) { 
  10.         curl_setopt($curl, CURLOPT_POST, 1); 
  11.         curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post)); 
  12.       } 
  13.       if($cookie) { 
  14.         curl_setopt($curl, CURLOPT_COOKIE, $cookie); 
  15.       } 
  16.       curl_setopt($curl, CURLOPT_HEADER, $returnCookie); 
  17.       curl_setopt($curl, CURLOPT_TIMEOUT, 20); 
  18.       curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
  19.       $data = curl_exec($curl); 
  20.       if (curl_errno($curl)) { 
  21.         return curl_error($curl); 
  22.       } 
  23.       curl_close($curl); 
  24.       if($returnCookie){ 
  25.         list($header$body) = explode("\r\n\r\n"$data, 2); 
  26.         preg_match_all("/Set\-Cookie:([^;]*);/"$header$matches); 
  27.         $info['cookie'] = substr($matches[1][0], 1); 
  28.         $info['content'] = $body
  29.         return $info
  30.       }else
  31.         return $data
  32.       } 
  33.   } 

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

举个栗子,代码如下:

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

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

  1. //登陆页面的隐藏字段   
  2.  
  3. function getView(){ 
  4.   $url = 'http://jw.hzau.edu.cn/default2.aspx'
  5.   $result = curl_request($url); 
  6.   $pattern = '/<input type="hidden" name="__VIEWSTATE" value="(.*?)" \/>/is'
  7.   preg_match_all($pattern$result$matches); 
  8.   $res[0] = $matches[1][0]; 
  9.        
  10.   return $res[0] ; 
  11.   //返回教室查询页面的隐藏值 
  12.   private function getViewJs($cookie,$xh){ 
  13.     $url = "http://jw.hzau.edu.cn/xxjsjy.aspx?xh={$xh}"
  14.     $result = curl_request($url,'',$cookie); 
  15.     $pattern = '/<input type="hidden" name="__VIEWSTATE" value="(.*?)" \/>/is'
  16.     preg_match_all($pattern$result$matches); 
  17.     $res[0] = $matches[1][0]; 
  18.     return $res[0] ; 
  19.   } 

4,cookie 的获取

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

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

  1. //返回课表字符串 
  2. private function classresult($xh,$pwd){ 
  3.     date_default_timezone_set("PRC"); //时区设置 
  4.     $classList = "";//声明课表变量 
  5.    
  6.     $cookie = $this->login($xh,$pwd); 
  7.     $view = $this->getViewJs($cookie,$xh);//验证密码是否正确 
  8.    
  9.     //如果密码正确 
  10.     if (!emptyempty($view)) { 
  11.       $url = "http://jw.hzau.edu.cn/xskbcx.aspx?xh={$xh}"
  12.       $result = curl_request($url,'',$cookie); //保存的cookies 
  13.       preg_match_all('/<table id="Table1"[\w\W]*?>([\w\W]*?)<\/table>/',$result,$out); 
  14.       $table = $out[0][0]; //获取整个课表 
  15.    
  16.       preg_match_all('/<td [\w\W]*?>([\w\W]*?)<\/td>/',$table,$out); 
  17.       $td = $out[1]; 
  18.       $length = count($td); 
  19.    
  20.       //获得课程列表 
  21.       for ($i=0; $i < $length$i++) { 
  22.         $td[$i] = str_replace("<br>"""$td[$i]); 
  23.    
  24.         $reg = "/{(.*)}/"
  25.          
  26.         if (!preg_match_all($reg$td[$i], $matches)) { 
  27.           unset($td[$i]); 
  28.         } 
  29.       } 
  30.    
  31.       $td = array_values($td); //将课程列表数组重新索引 
  32.       $tdLength = count($td); 
  33.       for ($i=0; $i < $tdLength$i++) { 
  34.         $td[$i] = iconv('GB2312','UTF-8',$td[$i]); 
  35.       } 
  36.    
  37.       //将课表转换成数组形式 
  38.       function converttoTable($table){ 
  39.         $list = array
  40.           'sun' => array
  41.             '1,2' => ''
  42.             '3,4' => ''
  43.             '5,6' => ''
  44.             '7,8' => ''
  45.             '9,10' => '' 
  46.           ), 
  47.           'mon' => array
  48.             '1,2' => ''
  49.             '3,4' => ''
  50.             '5,6' => ''
  51.             '7,8' => ''
  52.             '9,10' => '' 
  53.           ), 
  54.           'tues' => array
  55.             '1,2' => ''
  56.             '3,4' => ''
  57.             '5,6' => ''
  58.             '7,8' => ''
  59.             '9,10' => '' 
  60.           ), 
  61.           'wed' => array
  62.             '1,2' => ''
  63.             '3,4' => ''
  64.             '5,6' => ''
  65.             '7,8' => ''
  66.             '9,10' => '' 
  67.           ), 
  68.           'thur' => array
  69.             '1,2' => ''
  70.             '3,4' => ''
  71.             '5,6' => ''
  72.             '7,8' => ''
  73.             '9,10' => '' 
  74.           ), 
  75.           'fri' => array
  76.             '1,2' => ''
  77.             '3,4' => ''
  78.             '5,6' => ''
  79.             '7,8' => ''
  80.             '9,10' => '' 
  81.           ), 
  82.           'sat' => array
  83.             '1,2' => ''
  84.             '3,4' => ''
  85.             '5,6' => ''
  86.             '7,8' => ''
  87.             '9,10' => '' 
  88.           ) 
  89.         ); 
  90.         $week = array("sun"=>"周日","mon"=>"周一","tues"=>"周二","wed"=>"周三","thur"=>"周四","fri"=>"周五","sat"=>"周六"); 
  91.         $order = array('1,2','3,4','5,6','7,8','9,10'); 
  92.         foreach ($table as $key => $value) { 
  93.           $class = $value
  94.           foreach ($week as $key => $weekDay) { 
  95.             $pos = strpos($class,$weekDay); 
  96.             // echo $pos; 
  97.             if ($pos) { 
  98.               $weekArrayDay = $key//获取list数组中的第一维key 
  99.               foreach ($order as $key => $orderClass) { 
  100.                 $pos = strpos($class,$orderClass); 
  101.                 if ($pos) { 
  102.                   $weekArrayOrder = $orderClass//获取该课程是第几节 
  103.                   break
  104.                 } 
  105.               } 
  106.               break
  107.             } 
  108.           } 
  109.           $list[$weekArrayDay][$weekArrayOrder] = $class
  110.         } 
  111.         return $list
  112.       } 
  113.              
  114.       //调用函数 
  115.       return converttoTable($td); 
  116.     }else
  117.       return 0; 
  118.     } 
  119.   } 

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

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

总结起来就是这些了,每个学校的教务系统都不尽相同,这时我们可以借助火狐浏览器的 firebug 抓包,看看到底提交了哪些东西。

Tags: php模拟登陆

分享到: