教务网的那点事儿

来源:互联网 发布:vb滚动条设置字体大小 编辑:程序博客网 时间:2024/06/11 00:00

引言


一直对爬虫比较感兴趣,使用php写过一些小爬虫,爬过很多网站,然后收集有用的信息。php的curl库是一个很好用的工具,用来模拟请求爬取网页还是很方便的,使用方法也很简单。然后配上simple_html_dom,一个html的解析插件,一些简单的网页爬取工作就已经可以胜任了。后来发现python更适合来写爬虫,因为python拥有很多强大的库,借用网上的一些话:

  1. python 支持多线程,多进程(fork/deamon);
    2.python有丰富的异步模块、分析模块、爬虫模块以及爬虫相关的资料等等等等;

下面是一个简单的get请求:

  • php使用curl
$ch = curl_init();curl_setopt($ch,CURLOPT_REFERER,$url);curl_setopt($ch,CURLOPT_URL,$url);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$data = curl_exec($ch);
  • python使用requests库
import requestshtml = requests.get(url)print(html.text)

看起来,python代码比起php的就简洁一些。另外,本文的代码使用的php版本为7.+,python版本为3.5+。

那接下来就进入正题吧。


简介


本文使用php代码完整地讲诉如何一步步模拟登录教务网,然后取得课表等信息,使用python原理其实也都是一样的,只是对应的方法的具体实现不一样。php代码和python代码最后都会在结尾放出来。使用php而不是python的原因是,最初使用php实现登录的,python是后来自己根据php代码的原理移植的,总之原理都是差不多的。另外,这是我第一次在简书上写文章,介于水平有限,有错之处还望指正。


正文


这应该是最重要的一步了。我们知道,成功登录教务网后肯定是会返回一个cookie的,我们要做的就是,成功登录教务网,然后储存返回的cookie,再利用这个cookie去访问其他的链接。只要正确地得到了这个cookie,那就成功一大半了。下面就是详细地步骤:
1. 获取登录url
首先,打开谷歌浏览器,进入教务网首页,F12打开开发者工具,勾上Preserve log防止链接跳转找不到;然后输入正确的学号密码,于是成功得到了登录url:


2. 获取请求参数:


其中,最重要的前五个参数和最后一个参数,然后最难的就是获取第一个,第二个,以及最后一个参数了,下面就一一讲解每个参数的获取。

既然是通过表单提交的,又不是我们自己输入的,那就右键打开查看网页源代码吧。
于是乎找了半天,什么鬼,居然没找到?想了想,直接用get请求一下登录链接,然后把返回数据写入html文件中,找到里面的form标签,可以看到所有的参数都在里面,其中重要的代码:
<input name="__VIEWSTATE" type="hidden" value="*****",这就是那一串非常长非常蛋疼的参数,先放着,继续找;
<input name="__VIEWSTATEGENERATOR" type="hidden" value="CAA0A5A7"/>第二个参数也找到了;
<input id="efdfdfuuyyuuckjg" name="efdfdfuuyyuuckjg" type="hidden"/>,最后一个找是找到了,但是我要的value呢?这…
在最初的时候,这里困扰了我很长一段时间,导致我一直无法成功地登录,直到后来灵机一动,好吧,其实是听室友,成功模拟登录了的,说这是经过加密了参数。然后我突然醒悟了过来,于是,与教务网的斗争继续。
前端加密无非就是js了,寻找js,然后搜索有关“efdfdfuuyyuuckjg”的代码。按照这个思路,终于找了了其加密函数。其实就在返回的html数据中。其中有这么一段js代码:

function chkpwd(obj) {    var schoolcode = "10611";    var yhm = document.all.txt_dsdsdsdjkjkjc.value;    if (obj.value != "") {        if (document.all.Sel_Type.value == "ADM") yhm = yhm.toUpperCase();        var s = md5(yhm + md5(obj.value).substring(0, 30).toUpperCase() + schoolcode).substring(0, 30).toUpperCase();        document.all.efdfdfuuyyuuckjg.value = s;    } else {        document.all.efdfdfuuyyuuckjg.value = obj.value;    }}

结合表单中的
html<input id="efdfdfuuyyuuckjg" name="efdfdfuuyyuuckjg" type="hidden"/>,最后一个参数也就显而易见了。js加密过程如下:
1)将密码md5加密,然后截取前30个字符,并且变成大写字母;
2)将学号与第一步得到的字符串拼接,再与固定参数拼接,然后将整个字符串md5加密,截取前30个字母并且转为大写,就得到了加密过后的字符串,也就是input的value值。
既然得到了加密过程,那用php代码就很好实现了,代码如下:

function checkPwd($code, $pwd, $schoolcode) {     return strtoupper(substr(md5(($code . strtoupper(substr(md5($pwd), 0, 30)) . $schoolcode)), 0, 30));}

而第一个和第二个参数直接正则匹配出来就行了,代码如下:

function getView() {        $url     = $this->login_url;        $result  = $this->get($url);        $pattern = '/<input type="hidden" name="__VIEWSTATE" value="(.*?)" \/>/is';        preg_match_all($pattern, $result, $matches);        $res[0]  = $matches[1][0];        $pattern = '/<input type="hidden" name="__VIEWSTATEGENERATOR" value="(.*?)" \/>/is';        preg_match_all($pattern, $result, $matches);        $res[1] = $matches[1][0];        return $res;}

返回的数组就是两个参数的值。

3、请求结果

这样我们所有的参数都得到了,直接post带参数,得到返回数据,代码如下:

function post($url, $post_data) {        $this->cookie = dirname(__FILE__) . '\cookie_edu.txt';        $ch           = curl_init();        curl_setopt($ch, CURLOPT_URL, $url);        curl_setopt($ch, CURLOPT_HEADER, 0);        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        curl_setopt($ch, CURLOPT_POST, 1);        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);        curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookie);        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));        $result = curl_exec($ch);        curl_close($ch);        return $result;}

返回html界面
OK,登录成功。而且cookie我们也保存下来了。
那么在我们检测是否成功登录的时候,使用strpos函数检测返回的字符串中是否含有“正在加载权限数据”字符串就可以了,该函数返回出现该字符串的位置,若没有待检测字符串返回-1。

既然得到了cookie就好办了,直接抓取如成绩查询的url然后携带cookie去请求就行了,不管是get或者post都是可以的。比如get:

function get($url) {        $ch = curl_init();        curl_setopt($ch, CURLOPT_URL, $url);        curl_setopt($ch, CURLOPT_HEADER, 0);        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);        curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookie);        $result = curl_exec($ch);        return $result;}

试着抓取一下考试安排:


得到了下面的页面,注意这些url都可以F12抓包得到的,其它如获取成绩啊什么道理也是一样的,只要找到url,携带好cookie请求就可以了。


结语


整个过程基本就是这样了,其实有关模拟登陆步骤都是差不多的,只不过有的可能有验证码,有的加密过程更加复杂,比如腾讯的登陆加密过程实现是相当复杂,以前研究过不久就望而却步了。不过网上还是有大牛弄出来的。所以学习实在是无止境的,而自己要学的东西还有很多很多。

仓库地址:https://github.com/long2ice/edu.git

0 0
原创粉丝点击