[PHP]PHP爬虫 - URP教务

一、什么是爬虫?

网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。(来自百度百科)

二、爬虫准备

(一)基础知识

1.了解CURL爬虫过程

在这里插入图片描述

2.了解被爬网站(以URP教务为例)数据传输过程

(1)思路解析

A 、先打开登陆页面,获取cookies
B、再访问验证码的地址,因为验证码是动态的,每次打开都是不同的,所以我们需要保存之前的cookie,保证获取的验证码和后续要提交的表单是同步的
C、构建post表单请求数据,然后将数据提交给网站
D、获取响应头信息,通过返回的网页内容来判断是否登陆成功
E、登陆成功后模拟get请求获取数据,模拟post请求进行教学评估、选课等操作

3.正则匹配知识

(二)php环境搭建

1.php开启curl

具体怎么开启CSDN等网站上很多教程,不再补充

三、开始编码

(一)分析浏览器请求网页的流程

1.在web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML发送给浏览器。但是在没有携带cookie的情况下,如果IP短时间高并发的请求网站,该IP就会被封。
这里解释一下cookie,cookie是一种回话机制,可以用来存储很多信息,也经常用于反爬。
我们一般处理cookie有两种方法:
1、cookie的保存
2、cookie的读取
然后登陆部分的处理通常采用的方法就是将爬虫模拟成浏览器:
1、通过opener添加headers
2、通过requests添加headers
3、批量添加headers
本次采用的是第二种方法。
用浏览器打开教务处系统的界面如下:
在这里插入图片描述2.上面提到的headers,cookie等参数的获取,在登陆页面按F12进入开发者模式,选择network,再选中消息头,如图操作:(图片为火狐浏览器)
在这里插入图片描述

给大家解释下上图的主要信息,在伪装浏览器部分中,重点是获取请求的头部信息和服务器返回的响应头(response headers)。
1 request url :是浏览器真实请求的地址
2 accept :告诉浏览器自己接受什么类型
3 accept language :浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到
4 connection 表示是否是持久连接。
5 host 初始url中的主机端口
6 user-agent :浏览器类型
关于提交表单的获取,我们可以尝试故意输错账号或者密码得到提交的表单信息,即通过进入开发者工具抓包

(二)PHP爬虫代码核心部分解读

1. 验证码获取、保存、展示

	  //保存session会话
      $id = session_id();
      $_SESSION['id'] = $id;
      //cookie保存
      $cookie_jar = dirname(__FILE__) . '/cookie/'.$_SESSION['id'].'.txt';
      //模拟get请求获取验证码
      $random = '0.'.mt_rand(100000,999999).mt_rand(100000,999999).mt_rand(10000,99999);
      $url_img='http://zhjw.hbu.edu.cn/validateCodeAction.do?random='.$random;
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $url_img);
      curl_setopt($ch,CURLOPT_HEADER,0);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1) ;
      curl_setopt($ch, CURLOPT_TIMEOUT,6);
      curl_setopt($ch, CURLOPT_REFERER, 'http://zhjw.hbu.edu.cn/');
      curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_jar);
      $img = curl_exec($ch);
      //保存验证码到本地以便展示给用户
      $img_code = rand(0,500);
	  setcookie('img_cookie',$img_code);
      $img_name = 'vcode'.$img_code.'.jpg';
      $op_file = fopen('./images/'.$img_name, 'w');
      fwrite($op_file,$img);
      fclose($op_file);
      //关闭爬虫操作
      curl_close($ch);

展示:

 <img src="./images/<?php echo $img_name?>" alt="">

2.处理POST表单传过来的数据进行模拟登录

以json数据返回登录信息:$result

<?php
	header('Content-Type: application/json; charset=utf8');
	session_start();
	error_reporting(0);
	class Response{
	    /*
	     * 调用登陆
	     */
	    public function Login($post){
	        $cookie_jar = dirname(__FILE__) . '/cookie/'.$_SESSION['id'].'.txt';
	        $ch = curl_init("http://zhjw.hbu.edu.cn/loginAction.do");
	        curl_setopt($ch,CURLOPT_HEADER,0);
	        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1) ;
	        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	        curl_setopt($ch, CURLOPT_TIMEOUT,6);
	        curl_setopt($ch, CURLOPT_REFERER, 'http://zhjw.hbu.edu.cn/');
	        curl_setopt($ch, CURLOPT_POST,1) ;
	        curl_setopt($ch,CURLOPT_COOKIEFILE,$cookie_jar);
	        curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
	        $data = curl_exec($ch);
	        $this->Result($data);
	        curl_close($ch);
	    }
	
	    /*
	     * 登陆结果 输出json
	     */
	    public function Result($data) {
	        $data = iconv("gb2312","utf-8//IGNORE",$data);
	        $guize = '/<font color=\"#990000\">(.*?)<\/font/is';
	        preg_match_all($guize,$data,$big_class);
	       if(!empty($big_class[1][0])) {
	           //登录失败、组装数据返回
	           $result = array(
	               'Status' => 403,
	               'Title' => '提示:',
	               'Msg' => $big_class[1][0],
	           );
	           //变成json格式的
	            //JSON_UNESCAPED_UNICODE让中文不编码
	           echo json_encode($result, JSON_UNESCAPED_UNICODE);
	       }else{
	            //登录成功、组装数据返回
	            $result=array(
	                'Status'=>200,
	                'Title'=>'提示:',
	                'Msg'=>'登陆成功!',
	            );
	            //变成json格式的
	            //JSON_UNESCAPED_UNICODE让中文不编码
				echo json_encode($result,JSON_UNESCAPED_UNICODE);
	        }
	    }
	}
	$post = array(
			'zjh1' => '',
			'tips'=> '',
			'lx' => '',
			'evalue' => '',
			'eflag' => '',
			'fs' => '',
			'dzslh' => '',
			'zjh' => $_POST['zjh'],
			'mm' => $_POST['mm'],
			'v_yzm' => $_POST['v_yzm'],
		);
	$post=http_build_query($post);
	$login = new Response();
	$login->Login($post);
?>

3.登陆成功后模拟GET请求获取学生信息

 	 /*
	 * 模拟GET
	 */
	session_start();
	//注意修改成自己学校的教务地址,该地址为查看学籍信息显示
    $url = 'http://zhjw.xxx.edu.cn/xjInfoAction.do?oper=xjxx';
    //调用保存的cookies
    $cookie_jar = dirname(__FILE__) . '/cookie/'.$_SESSION['id'].'.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_TIMEOUT,6);
    curl_setopt($ch, CURLOPT_REFERER, 'http://zhjw.hbu.edu.cn/');
    curl_setopt($ch,CURLOPT_COOKIEFILE,$cookie_jar);
    $data=curl_exec($ch);
    curl_close($ch);
    $data = iconv("GBK","utf-8//IGNORE",$data);
    //var_dump($data);
    //正则匹配开始
    $guize = '/<td(.*?\s)width=\"275\">(.*?)<\/td>/is'
    //此结果 $arr_info[2][0] 为姓名,其他数据可以自己查看
    preg_match_all($guize,$data,$arr_info);

4.登陆成功后模拟POST请求进行教学评估

页面post方法将评估表中的数据传输到模拟请求的php界面

	session_start();
	class Response{
	    /*
	     * 模拟POST
	     */
	    public function JXPGPost($post){
	        $cookie_jar = dirname(__FILE__) . '/cookie/'.$_SESSION['id'].'.txt';
	        $ch = curl_init("http://zhjw.hbu.edu.cn/jxpgXsAction.do?oper=wjpg");
	        curl_setopt($ch,CURLOPT_HEADER,0);
	        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1) ;
	        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	        curl_setopt($ch, CURLOPT_TIMEOUT,6);
	        curl_setopt($ch, CURLOPT_REFERER, 'http://zhjw.hbu.edu.cn/jxpgXsAction.do');
	        curl_setopt($ch, CURLOPT_POST,1) ;
	        curl_setopt($ch,CURLOPT_COOKIEFILE,$cookie_jar);
	        curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
	        $data = curl_exec($ch);
	        curl_close($ch);
	        $this->Result($data);
	    }
	    /*
	     * 分析评教结果
	     */
	    public function Result($data) {
	        $data = iconv("gb2312","utf-8//IGNORE",$data);
	        $guize = '/alert\(\"(.*?)\"\)/is';
	        preg_match_all($guize,$data,$info);
	        echo "<div style = 'text-align:center'>
	                <br><h3>".$info[1][0]."</h3><br>";
	    }
	}
	//处理post过来的数据,修改格式
	$str = "";
	$flag = 0;
	foreach($_POST as $key=>$val) {
	    if($val == '')
	    {
	        $val = "";
	    }
	    if($flag == 0)
	    {
	        $str = $key."=".$val;
	        $flag ++;
	    }
	    else
	    {
	        $str = $str."&".$key."=".$val;
	    }
	}
	$login = new Response();
	$login->JXPGPost($str);

四、说明

因为源码已经在河北大学易班学生工作站使用,产权归易班学生工作站,所以不能公开源码,核心代码只有这几行,剩下的无非就是前端框架(我用的layui)和数据处理(比如:对爬取到的数据进行正则匹配)。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一杯糖不加咖啡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值