使用php的curl爬去青果教务系统 课表(转)
1. 分析
首先我们要了解 Http Cookie 的作用(可参考HTTP cookies 详解),简单来说就是维持一个会话,这样我们就能在登陆一个网页后,就能进入这个网页需要登陆的界面。
现在我们需要模拟登陆青果教务系统,就也需要先获取服务器给我们的cookie,然后用这个cookie值去获取验证码登陆,获取我们想要的内容。要注意的是有的网站对表头信息也是有验证的,我们需要在请求中添加表头信息。
总结起来就三部,首先获取登录界面的验证码并存储Cookie,然后通过cookie来模拟登陆,最后进入教务系统取想要的东西。
现在我们需要去留意的内容,各个请求的连接、header、和发送的数据
2. 查看请求
首先我们查看首页,我们发现登录并不在首页上,需要点击用户登录后才算进入了登录界面。
然后我们查看登录界面的请求。我们就是需要图中的Cookie 来登录,
在看验证码的请求,发现其中你的Cookie是一样的,所以,我们直接获取验证码的Cookie保存就行,不管登界面。
我们在看登录的请求,请求类型为POST,还是原来的cookie,但是我们发现传送的数据竟然那么多,其实,比多请求几次就会发现,其实有几个的值是永远不会变的,我们下面接着分析。
查看表单登录结构,发现刚才的提交数据都是隐藏的标签,并且都是大部分都是固定值,只有两个是我在输入密码或验证码时会一直变动,其实这两个就是密码和验证码,只是进行了特殊处理,这个网页引入了一个 md5.js 文件(上面第二张图中可以看到),加密就是通过这个文件进行的。
我们寻找加密部分的代码,在页面的某一部分,我们发现了加密的代码,我们在模拟登陆时就可以使用这部分处理了。
当我们登陆成功后我们课表的请求。OK,我们的心思收集工作完成了。下面开始编码吧。
3. 获取验证码和Cookie
首先我们需要一个界面来模拟登陆,我写了一个简单的html form登录,需要注意的是咋提交账号密码时要对信息使用 md5.js 加密。
- /**
- *test.html文件
- */
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport"
- content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
- <title>课表登录</title>
- </head>
- <body>
- <form action="./php/login.php" method="post">
- <div class="form-group">
- <input type="hidden" name="password" value="" id="password">
- <input type="hidden" name="validate" value="" id="validate">
- </div>
- <div class="form-group">
- <label for="id">学号:</label>
- <input type="number" class="form-control" id="id" name="txt_asmcdefsddsd" placeholder="" onblur="chkpwd()" onkeyup="chkpwd()">
- </div>
- <div class="form-group">
- <label for="exampleInputPassword1">密码:</label>
- <input type="password" class="form-control" id="exampleInputPassword1" name="txt_pewerwedsdfsdff" placeholder="Password" onblur="chkpwd()" onkeyup="chkpwd()">
- </div>
- <div class="form-group">
- <label for="exampleInputValidate">验证码:</label>
- <input type="text" class="form-control" id="exampleInputValidate" name="validatessss" placeholder="" onblur="chkyzm()" onkeyup="chkyzm()">
- <img src="./php/getValidate.php" onclick="changeValidateCode()" alt="" id="validateImg">
- </div>
- <button type="submit" class="btn btn-default">登录</button>
- </form>
- <script src="./js/jquery-3.2.1.min.js"></script>
- <script src="./js/md5.js"></script>
- <script>
- function changeValidateCode(){
- var Obj = $('#validateImg');
- var dt = new Date();
- var src = "./php/getValidate.php?t="+dt.getMilliseconds();
- Obj.attr('src', src);
- }
- function chkpwd() {
- var obj = $('#exampleInputPassword1');
- if(obj.val()!='') {
- var s = md5($('#id').val()+md5(obj.val()).substring(0,30).toUpperCase()+'10467').substring(0,30).toUpperCase();
- $('#password').attr("value",s);
- } else {
- $('#password').attr("value",'');
- }
- }
- function chkyzm() {
- var obj = $('#exampleInputValidate');
- if(obj.val()!='') {
- var s=md5(md5(obj.val().toUpperCase()).substring(0,30).toUpperCase()+'10467').substring(0,30).toUpperCase();
- $('#validate').attr("value",s);
- } else {
- $('#validate').attr("value",'');
- }
- }
- </script>
- </body>
- </html>
我们来获取验证码 ,注意的是我是吧Cookie存储到了本地
- /**
- */php/getValidate.php文件
- */
- <?php
- //Cookie存储文件
- $cookie_file = dirname(__FILE__)."/../cookie/tmp.cookie";
- if(!file_exists($cookie_file)) {
- $myfile = fopen($cookie_file, "w");
- fclose($myfile);
- }
- $t = isset($_GET['t'])?$_GET['t']:0;
- $verify_code_url = "http://jwgl.xxxxxx.edu.cn/jwweb/sys/ValidateCode.aspx?t=".$t;
- //不用纠结那条需要不需要,直接header都写上是不会错的
- $header = [
- 'Accept:image/webp,image/apng,image/*,*/*;q=0.8',
- 'Accept-Encoding:gzip, deflate',
- 'Accept-Language:zh-CN,zh;q=0.8',
- 'Cache-Control:no-cache',
- 'Connection:keep-alive',
- 'Host:jwgl.xxxx.edu.cn', //修改名称
- 'Pragma:no-cache',
- 'Referer:http://jwgl.xxxxx.edu.cn/jwweb/_data/login.aspx',//修改名称
- 'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36',
- ];
- $curl = curl_init();
- curl_setopt($curl,CURLOPT_HTTPHEADER,$header); //设置表头
- curl_setopt($curl, CURLOPT_URL, $verify_code_url); // 设置请求地址
- curl_setopt($curl,CURLOPT_COOKIEJAR,$cookie_file); //获取COOKIE并存储
- $img = curl_exec($curl);
- curl_close($curl);
- //输出图片到html
- echo $img;
当进入test.html 时,cookie文件夹下就有存储的Cookie了
4. 模拟登陆
然后我们模拟登录,主要的地方是要用之前存储的Cookie和用Post请求
- //Cookie路径
- $cookie_file = dirname(__FILE__)."/../cookie/tmp.cookie";
- $url = 'http://jwgl.xxxx.edu.cn/jwweb/_data/index_LOGIN.aspx';
- $post = [
- '__VIEWSTATE' => 'dDw4ODEwMTkyNTY7Oz6uXw9RQf0bw8SrGIjZutgOtpxLCw==',
- '__VIEWSTATEGENERATOR' =>'4B596BA9',
- 'pcInfo' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3080.5 Safari/537.36undefined5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3080.5 Safari/537.36 SN:NULL',
- 'typeName' => '(unable to decode value)',
- 'dsdsdsdsdxcxdfgfg' => $_POST['password'],
- 'fgfggfdgtyuuyyuuckjg' => $_POST['validate'],
- 'Sel_Type' => 'STU',
- 'txt_asmcdefsddsd' => $_POST['txt_asmcdefsddsd'],
- 'txt_pewerwedsdfsdff'=> '',
- 'txt_sdertfgsadscxcadsads' => '',
- 'sbtState' => '',
- ];
- $post = http_build_query($post);
- $headers = array(
- "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
- "Accept-Encoding:gzip, deflate",
- "Accept-Language:zh-CN,zh;q=0.8",
- "Cache-Control:max-age=0",
- "Content-Length:603",
- "Content-Type:application/x-www-form-urlencoded",
- "Host:jwgl.xxxx.edu.cn",
- "Origin:http://jwgl.xxxx.edu.cn",
- "Proxy-Connection:keep-alive",
- "Referer:http://jwgl.xxxx.edu.cn/jwweb/_data/index_LOGIN.aspx",
- "Upgrade-Insecure-Requests:1",
- "User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3080.5 Safari/537.36",
- );
- $curl = curl_init();
- curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);//设置header
- curl_setopt($curl, CURLOPT_URL, $url); //设置url
- curl_setopt($curl, CURLOPT_POST, true); // 设置为POST请求
- curl_setopt($curl, CURLOPT_RETURNTRANSFER,1); // 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
- curl_setopt($curl, CURLOPT_POSTFIELDS, $post); //传送的数据
- curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie_file); //设置cookie
- $result=curl_exec($curl);
- //可以输出当前信息看看是否登录成功
- //$file = dirname(__FILE__)."/../html/test.html";
- //$fp = fopen($file,"w");
- //fwrite($fp,$result);
- //fwrite($fp, '结束');
- //fclose($fp);
5. 获取数据
到此,我们已经登录成功了,然后我们就可以进入系统提取数据了,比如提取课表信息。
- $curl = curl_init();
- $url = 'http://jwgl.xxx.edu.cn/jwweb/wsxk/stu_zxjg_rpt.aspx';
- curl_setopt($curl, CURLOPT_URL, $url);
- curl_setopt($curl, CURLOPT_HEADER, false);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);
- curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie_file);
- $result=curl_exec($curl);
- $file = dirname(__FILE__)."/../html/test.html";
- $fp = fopen($file,"w");
- fwrite($fp,$result);
- fclose($fp);
对于上面的 curl函数 也可以使用封装好的库Guzzle 替换来发送请求
6. 提取数据
当我们得到网页文本时,并不是我们的最终目的,我们要的是其中除了html标签之外的数据。关于提取数据,我推荐大家使用symfony/dom-crawler,再配合他的symfony/css-selector来将html文本转换成结点,通过CSS选择器方式定位结点获取相应的数据。
注:本文转自:http://blog.csdn.net/mrwangweijin/article/details/77194994,如需转载请注明出处:https://www.cnblogs.com/zhuchenglin/p/7732352.html
使用php的curl爬去青果教务系统 课表(转)的更多相关文章
- 从爬取湖北某高校hub教务系统课表浅谈Java信息抓取的实现 —— import java.*;
原创文章与源码,如果转载请注明来源. 开发环境:Myeclipse,依赖包:apache-httpclient . Jsoup.base64 一.概述 整个系统用Java开发.我们现在要做的是类似于超 ...
- 用Python爬虫爬取广州大学教务系统的成绩(内网访问)
用Python爬虫爬取广州大学教务系统的成绩(内网访问) 在进行爬取前,首先要了解: 1.什么是CSS选择器? 每一条css样式定义由两部分组成,形式如下: [code] 选择器{样式} [/code ...
- python unicode 转中文 遇到的问题 爬去网页中遇到编码的问题
How do convert unicode escape sequences to unicode characters in a python string 爬去网页中遇到编码的问题 Python ...
- java批量爬去电影资源
摘要 网上有很多个人站来分享电影资源,其实有时候我们自己也想做这个一个电影站来分享资源.但是这个时候就有一个问题,电影的资源应该从哪里来呢?难道要自己一条条手动去从网络上获取,这样无疑是缓慢而又效率低 ...
- 利用python的爬虫技术爬去糗事百科的段子
初次学习爬虫技术,在知乎上看了如何爬去糗事百科的段子,于是打算自己也做一个. 实现目标:1,爬取到糗事百科的段子 2,实现每次爬去一个段子,每按一次回车爬取到下一页 技术实现:基于python的实现, ...
- python爬去电影天堂恐怖片+游戏
1.爬去方式python+selenium 2.工作流程 selenium自动输入,自动爬取,建立文件夹,存入磁力链接到记事本 3.贴上代码 #!/usr/bin/Python# -*- coding ...
- Java基础-爬虫实战之爬去校花网网站内容
Java基础-爬虫实战之爬去校花网网站内容 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 爬虫这个实现点我压根就没有把它当做重点,也没打算做网络爬虫工程师,说起爬虫我更喜欢用Pyt ...
- Python学习之路 (五)爬虫(四)正则表示式爬去名言网
爬虫的四个主要步骤 明确目标 (要知道你准备在哪个范围或者网站去搜索) 爬 (将所有的网站的内容全部爬下来) 取 (去掉对我们没用处的数据) 处理数据(按照我们想要的方式存储和使用) 什么是正则表达式 ...
- selenium爬去数据+存储
1 爬去数据代码 #coding=utf-8 from selenium import webdriver from selenium.webdriver.common.by import By fr ...
随机推荐
- Mysql漏洞修复方法思路及注意事项
[系统环境] 系统环境:Red Hat Enterprise Linux Server release 5.4 (Tikanga) + 5.7.16 MySQL Community Server ...
- 我的 Erdos 数是 4
我的 Erdos 数是 4. 呵呵. 图书馆开通了一个月的 mathscinet 数据库查询. 本来想买个 pde 的最新进展, 结果不能查询, 就算了.
- [再寄小读者之数学篇](2014-06-20 Beta 函数)
令 $\dps{B(m,n)=\sum_{k=0}^n C_n^k \cfrac{(-1)^k}{m+k+1}}$, $m,n\in\bbN^+$. (1) 证明 $B(m,n)=B(n,m)$; ( ...
- [物理学与PDEs]第1章第7节 媒质中的 Maxwell 方程组 7.1 媒质中的 Maxwell 方程组
1.媒质的极化 (1) 束缚电荷: 被束缚在原来位置上的电荷. (2) 在电磁场中, 束缚电荷会有一微小的运动, 而产生电偶极矩. 此即称为媒质的极化. (3) 设电极化强度 (单位体积的电偶极矩) ...
- 使用sessionStorage、localStorage存储数组与对象
先介绍一下localStorage localStorage对象是HTML5的客户端存储持久化数据的方案.为了能访问到同一个localStorage对象,页面必须来自同一个域名(子域名无效),使用同一 ...
- Mysq登陆后执行命令提示You must SET PASSWORD before executing this statement
mysql 安装完成后,在输入命令行时,提示:You must SET PASSWORD before executing this statement 提示必须设置密码,我想不是已经设置了密码吗? ...
- java(10)类的无参方法
一.变量的作用域(有效的使用范围) 1.变量有2种 1.1成员变量(属性) 声明在类的里面,方法的外面 1.2 局部变量 声明在方法里面或for循环结构中 2.调用时的注意事项(初始值不同.作用域不同 ...
- mysql 时间格式转换
1.varchar 转 datetime 格式 DATE_FORMAT(time,'%Y-%m-%d %H:%m:%s'); 2.时间减去一小时 DATE_FORMAT(date_add(time ...
- 第三章 Java的基础程序设计结构
一个简单的 Java 应用程序 访问修饰符 public,private,protected main 方法必须时public修饰的,C#则不必须 数据类型 可以用16进制表示浮点数 可以用2,8,1 ...
- TCP-IP详解学习笔记1
TCP-IP详解学习笔记1 网关可以在互不相关的网络之间提供翻译功能: 体系结构: 协议和物理实现,实际上是一组设计决策. TCP/IP协议族允许计算机,智能手机,嵌入式设备之间通信: TCP/IP是 ...