ICCMO微信公众账号开发系列(3)CURL模拟登陆教务系统查成绩

上一篇提到CURL。咱们这一篇来玩玩它。
    CURL 是什么呢?
    CURL有什么用?
    咱们今天通过CURL模拟登陆教务系统查成绩来学习一下这个函数。
    今天要实现的功能是:通过微信查成绩。
    原理:
    怎么实现的呢?
   就是模拟登陆。什么是模拟登陆?通俗一点的说法就是,模拟咱们的浏览器去登陆咱们的教务系统。怎么实现登陆的呢。这就得用到CURL类的函数了。下面我们来看看原理图。
   ![这里写图片描述](https://img-blog.csdn.net/20150801154152948)
   现在我们模拟登陆教务系统,把成绩抓过来再返回给我们的手机。
   ![原理](https://img-blog.csdn.net/20150801154340651)

正常情况下我们查成绩是登陆教务系统网站,输入学号和密码,登陆成功,然后点击查看成绩。今天我们要实现的就是模拟浏览器发送账号密码并取回成绩。大家知道,浏览器有两种传值方法GET和POST。(有的说有3种,有一种不常用)GET方法就是通过URL传值,一般我们是可以在地址栏看得到的。就是这种形式http://www.baidu.com?word=“xxxx”。POST传值一般我们是看不到的,但是我们可以通过抓包看得到。做模拟登录最重要的就是保存cookie。cookie是一种会话技术,http连接是一种无状态的连接,网站不知道是谁发送的请求,需要一种标识来记录用户身份。Cookie是由教务系统服务器端生成,发送给浏览器,浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求教务系统网站时就发送该Cookie给服务器。Cookie名称和值可以由服务器端开发自己定义,这样服务器可以知道该用户是否合法用户以及是否需要重新登录等,服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。所以咱们发送完数据的时候记得保存cookie。到时候咱们再请求页面的时候直接发送cookie就可以了。
下面我以中南民族教务系统演示一下抓包。
打开中南民族大学教务系统首页,输入学号和密码。

这里写图片描述

    在点击登陆之前按下F12,我们通过谷歌浏览器自带的这个抓包就可以了。当然你也可以用你习惯的抓包工具。F12,在上面一栏点击NetWork。![这里写图片描述](https://img-blog.csdn.net/20150801160718361)

点击登陆,然后注意看看下面控制台的变化。
这里写图片描述
咱们一点击登陆,浏览器就发了这么多请求,到底哪个是咱们想要的呢请求呢?找到第一条POST请求。右键,我们看看浏览器发了什么给教务系统系统服务器。
这里写图片描述

这里写图片描述
看图中的1和2是我的账号密码,浏览器就是把DATA下面的数据通过POST形式发送给教务系统服务器的。下面我们通过代码来模拟浏览器的行为。
右键第一条POST请求,选择Copy as CURL。
这里写图片描述
把复制出来的东西粘贴到编辑器里,待会会用到。
这里写图片描述
curl开头的这一行是我们请求的地址。
-H开头的都是请求头。
-data开头的是我们要模拟发送的数据。
这里我们只需要留:curl和-data开头的就行了。
curl:
http://ids.scuec.edu.cn/amserver/UI/Login
–data :”IDToken0=&IDToken1=我的账号&IDToken2=我的密码&IDButton=Submit&goto=aHR0cDovL215LnNjdWVjLmVkdS5jbi9pbmRleC5wb3J0YWw”%”3D&encoded=true&gx_charset=UTF-8”
这时可以清空控制台下面的请求了。待会继续看成绩的页面也抓包,主要是为了获取成绩页面的URL地址。这里说明一下:我这里不是直接进的教务系统,而是进的信息门户,信息门户集成了中门民族大学的大部分系统。中南民族大学教务系统有验证码,模拟登录起来比较麻烦,所以我就绕道而行,如果以后把自动识别验证码做出来的话,可以直接从这里模拟登录。不过有学校的教务系统有漏洞,不用验证码也可成功登录。带验证码登录的我也做过,就是靠人工识别,自己写程序识别识别率不是很高,经常导致模拟登录失败。废话不多说了。咱们把请求成绩的URL地址找出来。你根据你自己的情况来。我这里是先跳转到中南民族大学教务系统,跳转的时候需要再保存一次cookie。然后再点击请求成绩页面。
这两个URL地址在地址栏就可以复制出来。

新建一个test.php文件,咱们用CURL来模拟浏览器登录教务系统:记得保存cookie。

来说一下这个CURL类。
CURL基本的使用方法:
1.初始化,创建一个新cURL资源
2.设置URL和相应的选项
3.抓取URL并把它传递给浏览
4.关闭cURL资源,并且释放系统资源
直接上代码,代码里有注释。

<?php
/*
 * 查成绩功能
 *
*/
    $username="你的账户";
    $password="你的密码";
    $cookie_file  = tempnam('./temp','cookie');

   // $cookie_file = tempnam(SAE_TMP_PATH, 'cookie');//在SAE下用这个
    $login_url  ='http://ids.scuec.edu.cn/amserver/UI/Login';//信息门户登陆地址
    $post_fields ="encoded=true&goto=aHR0cDovL215LnNjdWVjLmVkdS5jbi9pbmRleC5wb3J0YWw=&gx_charset=UTF-8&IDButton=Submit&IDToken0=&IDToken1=".$username."&IDToken2=".$password;//这是post的数据
    $ch = curl_init($login_url);//初始化
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//这儿参数1,不输出,后面如果有输出函数也能输出页面
    curl_setopt($ch, CURLOPT_POST, 1);//使用的是post方法,参数为1
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);//需要post的数据
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);//这句的作用就是保存cookie
    $content=curl_exec($ch);
    curl_close($ch);

    //模拟登陆教务系统
    $url='http://ssfw.scuec.edu.cn/ssfw/j_spring_ids_security_check';//这是转到教务系统页面
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);//这里会用到前面保存的cookie
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
    $contents = curl_exec($ch); //执行,得到是字符串,赋值给contents,$contents变量的类型是string
   // print_r($contents);
    //die;

    //成绩查询页面       
    $url='http://ssfw.scuec.edu.cn/ssfw/zhcx/cjxx.do';//这次请求的就是成绩页面
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);//这里会用到前面保存的cookie
    $contents = curl_exec($ch);
    curl_close($ch);
    print_r($contents);

运行一下这个文件,看看,已经可以抓到成绩的页面了,咱们再成正则表达式把我们需要的内容提取出来。咱们只需要这个学期的成绩。好,继续加代码。这里写图片描述

<?php
/*
 * 查成绩功能
 *
*/
 //header('Content-Type: text/html; charset=UTF-8');
   function chengji($username,$password){
    //$cookie_file  = tempnam('./temp','cookie');
    $cookie_file = tempnam(SAE_TMP_PATH, 'cookie');//在SAE下用这个
    $login_url  ='http://ids.scuec.edu.cn/amserver/UI/Login';//信息门户登陆地址
    $post_fields ="encoded=true&goto=aHR0cDovL215LnNjdWVjLmVkdS5jbi9pbmRleC5wb3J0YWw=&gx_charset=UTF-8&IDButton=Submit&IDToken0=&IDToken1=".$username."&IDToken2=".$password;//这是post的数据
    $ch = curl_init($login_url);//初始化
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//这儿参数1,不输出,后面如果有输出函数也能输出页面
    curl_setopt($ch, CURLOPT_POST, 1);//使用的是post方法,参数为1
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);//需要post的数据
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);//这句的作用就是保存cookie
    $content=curl_exec($ch);
    curl_close($ch);

    //模拟登陆教务系统
    $url='http://ssfw.scuec.edu.cn/ssfw/j_spring_ids_security_check';//这是转到教务系统页面
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);//这里会用到前面保存的cookie
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
    $contents = curl_exec($ch); //执行,得到是字符串,赋值给contents,$contents变量的类型是string
    curl_close($ch);

    //成绩查询页面       
    $url='http://ssfw.scuec.edu.cn/ssfw/zhcx/cjxx.do';//这次请求的就是成绩页面
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);//这里会用到前面保存的cookie
    $contents = curl_exec($ch);

    if(!empty($contents))
      {
        $match="|(<=<td>).*(?=</td>)|";
        preg_match_all( '/<table class="table_con" base="color3" width="100%" border="0" align="center" cellpadding="0" cellspacing="0">[^>]*>([\s\S]*?)<\/table>/', $contents, $mycontents);//正则匹配成绩那一表格
        $arr = get_td_array($mycontents[0][0]);
        array_shift($arr);
        array_pop($arr);
        $result="-------------我的成绩---------------\n";
        if(count($arr)>0){  
        for($i=0;$i<count($arr);$i++){
            $result .=trim($arr[$i][3]);
            $result .= trim($arr[$i][7])."\n";

          }
        }else{
            $result= "您的考试成绩还没出来哦O(∩_∩)O~";
        }
    }else{
         $result= "登陆教务系统失败!!!";
     }

        return $result; 

 }     

function get_td_array($table) {
        $table = preg_replace("'<table[^>]*?>'si","",$table);
        $table = preg_replace("'<tr[^>]*?>'si","",$table);
        $table = preg_replace("'<td[^>]*?>'si","",$table);
        $table = str_replace("</tr>","{tr}",$table);
        $table = str_replace("</td>","{td}",$table);
        //去掉 HTML 标记
        $table = preg_replace("'<[/!]*?[^<>]*?>'si","",$table);
        //去掉空白字符
        $table = preg_replace("'([rn])[s]+'","",$table);
        $table = preg_replace('/&nbsp;/',"",$table);
        $table = str_replace(" ","",$table);
        $table = str_replace(" ","",$table);
        $table = explode('{tr}', $table);
        //array_pop($table);
        foreach ($table as $key=>$tr) {
                $td = explode('{td}', $tr);
                //array_pop($td);
            $td_array[] = $td;
        }
        return $td_array;
}


到这里咱们的成绩处理就处理完了。根据你的情况处理成绩。
现在我们把他接入微信。
新建一个index.php文件

把上面的成绩页面引进来。
$keywords = explode("+",$keyword);

                $username=$keywords[1];
                $password= $keywords[2]; 
                $contentStr=chengji($username,$password);

“`
58行的这断是把微信发过来的消息拆分,我们约定查询的格式为:成绩+学号+密码。当然你也可以存到数据库里,查询的时候先要求绑定学号,然后再从数据库里面查询。这里我们就直接拆分为三个字段了。
好,把代码打包上传到SAE。咱们来测试一把。
这里写图片描述

成功了。完整代码包下载:点击下载
查询课表,查询考试安排的原理也是一样的。有什么问题联系我,QQ648988391。QQ交流群:429207338

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值