首页 > 开发 > PHP > 正文

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

2024-05-04 23:35:24
字体:
来源:转载
供稿:网友

这篇文章主要介绍了php实现模拟登陆方正教务系统抓取课表的相关资料,需要的朋友可以参考下

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

其实稍微了解一点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. if($cookie) { 
  13. curl_setopt($curl, CURLOPT_COOKIE, $cookie); 
  14. curl_setopt($curl, CURLOPT_HEADER, $returnCookie); 
  15. curl_setopt($curl, CURLOPT_TIMEOUT, 20); 
  16. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
  17. $data = curl_exec($curl); 
  18. if (curl_errno($curl)) { 
  19. return curl_error($curl); 
  20. curl_close($curl); 
  21. if($returnCookie){ 
  22. list($header$body) = explode("/r/n/r/n"$data, 2); 
  23. preg_match_all("/Set/-Cookie:([^;]*);/"$header$matches); 
  24. $info['cookie'] = substr($matches[1][0], 1); 
  25. $info['content'] = $body
  26. return $info
  27. }else
  28. return $data

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

举个栗子

复制代码代码如下:

 

  1. <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']; 

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. $td = array_values($td); //将课程列表数组重新索引 
  30. $tdLength = count($td); 
  31. for ($i=0; $i < $tdLength$i++) { 
  32. $td[$i] = iconv('GB2312','UTF-8',$td[$i]); 
  33.  
  34. //将课表转换成数组形式 
  35. function converttoTable($table){ 
  36. $list = array
  37. 'sun' => array
  38. '1,2' => ''
  39. '3,4' => ''
  40. '5,6' => ''
  41. '7,8' => ''
  42. '9,10' => '' 
  43. ), 
  44. 'mon' => array
  45. '1,2' => ''
  46. '3,4' => ''
  47. '5,6' => ''
  48. '7,8' => ''
  49. '9,10' => '' 
  50. ), 
  51. 'tues' => array
  52. '1,2' => ''
  53. '3,4' => ''
  54. '5,6' => ''
  55. '7,8' => ''
  56. '9,10' => '' 
  57. ), 
  58. 'wed' => array
  59. '1,2' => ''
  60. '3,4' => ''
  61. '5,6' => ''
  62. '7,8' => ''
  63. '9,10' => '' 
  64. ), 
  65. 'thur' => array
  66. '1,2' => ''
  67. '3,4' => ''
  68. '5,6' => ''
  69. '7,8' => ''
  70. '9,10' => '' 
  71. ), 
  72. 'fri' => array
  73. '1,2' => ''
  74. '3,4' => ''
  75. '5,6' => ''
  76. '7,8' => ''
  77. '9,10' => '' 
  78. ), 
  79. 'sat' => array
  80. '1,2' => ''
  81. '3,4' => ''
  82. '5,6' => ''
  83. '7,8' => ''
  84. '9,10' => '' 
  85. ); 
  86. $week = array("sun"=>"周日","mon"=>"周一","tues"=>"周二","wed"=>"周三","thur"=>"周四","fri"=>"周五","sat"=>"周六"); 
  87. $order = array('1,2','3,4','5,6','7,8','9,10'); 
  88. foreach ($table as $key => $value) { 
  89. $class = $value
  90. foreach ($week as $key => $weekDay) { 
  91. $pos = strpos($class,$weekDay); 
  92. // echo $pos; 
  93. if ($pos) { 
  94. $weekArrayDay = $key//获取list数组中的第一维key 
  95. foreach ($order as $key => $orderClass) { 
  96. $pos = strpos($class,$orderClass); 
  97. if ($pos) { 
  98. $weekArrayOrder = $orderClass//获取该课程是第几节 
  99. break
  100. break
  101. $list[$weekArrayDay][$weekArrayOrder] = $class
  102. return $list
  103.  
  104. //调用函数 
  105. return converttoTable($td); 
  106. }else
  107. return 0; 

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)); 

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

以上所述就是本文的全部内容了,希望大家能够喜欢。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表