江西干部网站学院老版自动学习PHP源码

发布于2019-10-28 22:11:26  分类:php   阅读( 64 ) 

江西干部网站学院网站已经改版,页面美观了许多,后台逻辑也更加完善了,这个版本的源码已不能正常使用,仅写下来研究学习原理。

实现目标:用户登录后,将cookie保存为文件,路径写入数据库以备保持登录和自动登录。登录后,如果用户学时没有达到目标90分,则自动选课,自动学习,直到90分为止。

前台文件打包:jxgbxx.zip

后台设计:

a1. 路由设置

//江西干部网络学习
Route::get('/jxgb', 'JxgbxxController@index')->name('jxgbxx')->middleware('verified');//江西干部网络学习首页,需要验证邮箱的用户才能访问
Route::post('/jxgbindex2', 'JxgbxxController@index2')->name('gb.index2');//登录本站查询数据库
Route::post('/jxgblogin', 'JxgbxxController@login')->name('gb.jxjylogin');//登录官网获取cookie
Route::get('/jxgbupdatetime', 'JxgbxxController@updatetime')->name('gb.updatetime');//每5分钟访问该页面更新学习时间

a2. 模型JxgbxxModel.php

namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class JxgbxxModel extends Model
{
    protected $table = 'jxgbxx_gj';
protected $guarded = [];//禁止批量赋值的字段
}

a3. 控制器JxgbxxController.php,代码比较长,主要是post比较复杂:

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Encore\Admin\Widgets\Form;
use Encore\Admin\Show;
use App\Models\JxgbxxModel;
class JxgbxxController extends Controller
{
public function __construct()
    {
        $this->middleware('auth', [            
            'except' => ['login', 'index2','updatetime']//过滤未登录用户除非login之外的操作
        ]);
    }
//首页
public function index()
{
        return view('home/jxgbxx/index');
    }
//判断是否需要获取cookie,切换学科id时,需要重新获取cookie
public function index2(Request $request)
{
$username = $request['username'];
$password = $request['password'];
//判断是否存在记录
$sfcz = JxgbxxModel::where('username',$username)->count();
if($sfcz > 0){
//存在记录,则获取数据库密码,如果匹配就进入控制台,否则报错返回
$dbpas = JxgbxxModel::where('username',$username)->value('password');
$JSESSIONID = JxgbxxModel::where('username',$username)->value('JSESSIONID');
if($password == $dbpas and $JSESSIONID !== ''){
$cxjgs = JxgbxxModel::where('username',$username)->first();
//dd($cxjgs);
return view('home/jxgbxx/yhmb', compact('cxjgs'));//传递数组到查询用户面板视图
}elseif($password !== $dbpas){
echo "<script language=javascript>alert('密码错误,请重新输入!');history.back();</script>";
}elseif($password == $dbpas and $JSESSIONID == ''){
//被删除$JSESSIONID重新登录
session_start();
$id = session_id();
$_SESSION['id'] = $id;
// 验证码保存
$cookie_jar = 'uploads/temp/'.$_SESSION['id'].'.txt';
$url_img='http://www.jxgbwlxy.gov.cn/portal/index!imgcode.action?a=1571273293510';
$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_COOKIEJAR, $cookie_jar);
$img = curl_exec($ch);
curl_close($ch);
$img_code = rand(0,500);
$img_name = 'vcode'.$img_code.'.jpg';
$op_file = fopen('uploads/temp/'.$img_name, 'w');
fwrite($op_file,$img);
fclose($op_file);
$yzmtp = 'uploads/temp/'.$img_name;
        return view('home/jxgbxx/index2',compact('yzmtp','username','password'));
}
}else{
//不存在记录,则需要登录官网获取cookie
session_start();
$id = session_id();
$_SESSION['id'] = $id;
// 验证码保存
$cookie_jar = 'uploads/temp/'.$_SESSION['id'].'.txt';
$url_img='http://www.jxgbwlxy.gov.cn/portal/index!imgcode.action?a=1571273293510';
$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_COOKIEJAR, $cookie_jar);
$img = curl_exec($ch);
curl_close($ch);
$img_code = rand(0,500);
$img_name = 'vcode'.$img_code.'.jpg';
$op_file = fopen('uploads/temp/'.$img_name, 'w');
fwrite($op_file,$img);
fclose($op_file);
$yzmtp = 'uploads/temp/'.$img_name;
        return view('home/jxgbxx/index2',compact('yzmtp','username','password'));
}
}
  //登录官网
    public function login(Request $request)
    {
//$data = $request->all();
//dd($data);
$username = $request['username'];
$password = $request['password'];
$yzm = $request['yzm'];
$fhsj = $this->getcas($username,$password,$yzm);//必修学时
//dd($fhsj);
if ($fhsj[0] == ''){
echo "<script language=javascript>alert('登录失败!');history.back();</script>";
}else{
$name = $fhsj[0];//真实姓名
$zxs = $fhsj[1];//总学时
$bxxs = $fhsj[2];//必修学时
$xxxs = $fhsj[3];//选修学时
$JSESSIONID = $fhsj[4];//登录凭证
$cxjgs = JxgbxxModel::updateOrCreate(['username' => $username],['password' => $password,'JSESSIONID' => $JSESSIONID,'name' => $name,'zxs' => $zxs,'bxxs' => $bxxs,'xxxs' => $xxxs]);
//dd($JSESSIONID);
return view('home/jxgbxx/yhmb', compact('cxjgs'));//传递数组到查询用户面板视图
}
    }
    //官网获取$JSESSIONID
    public function getcas($username,$password,$yzm)
{
session_start();
$cookie_jar = 'uploads/temp/'.$_SESSION['id'].'.txt';
$arr_header[] = "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
$i = 0;//避免死循环
do {
$url = "http://www.jxgbwlxy.gov.cn/j_security_check";
$post1 = "j_username=$username&j_password=$password&imgCode=$yzm&j_uri=/student/student.action";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, 1);//post方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $post1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);//超时10秒中止访问,防止卡住
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);//抓取跳转后数据
curl_setopt($ch, CURLOPT_HTTPHEADER, $arr_header);//设置协议头
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置为0,只返回成功或失败,设置为1则返回网页源码
//curl_setopt($ch, CURLOPT_COOKIE, "");//CURLOPT_COOKIE提交cookie
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_jar); //这里就是使用验证码cookie文件的地方
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_jar);//登录成功后保存新cookie
curl_setopt($ch, CURLOPT_REFERER, '$url');  //302跳转需要referer,也可以用来伪装来源
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$content = curl_exec($ch);
//dd($content);
$name = trim($this->getSubstr($content,'<div class="name">',"</div>"));//姓名
$zxs = trim($this->getSubstr($content,'style="color: #30658d;">',"</span></div>"));//总学时
$bxxs = trim($this->getSubstr($content,"必修学时<span>","</span></div>"));//必修学时
$xxxs = trim($this->getSubstr($content,"选修学时<span>","</span></div>"));//选修学时
$i++;
unset($url);//解决curl在循环体中只执行一次问题
unset($post1);
if ($i >10){
return '登录失败';
break;}//避免死循环
}while ($bxxs == '');
curl_close($ch);//循环体外关闭
return array($name,$zxs,$bxxs,$xxxs,$cookie_jar);
}
    //定时运行脚本,每20分钟由阿里云监控访问本页面,该脚本读取数据库,总学时小于100的,加入数据,运行更新程序
    public function updatetime()
{
$data = JxgbxxModel::where('bxxs','<', 100)->get();
//dd($data);
if(count($data) < 1){
return redirect()->route('jxgbxx');//跳转首页登录
}
//循环执行更新程序
foreach ($data as $key=>$value)
{
$username = $value["username"];
$JSESSIONID = $value["JSESSIONID"];
$name = $value["name"];
$password = $value["password"];
$oldrizhi = $value["rizhi"];
//dd($username);
//获取未完成的课程id
$cxjgs = $this->getkcid($JSESSIONID);//array($kcid,$zxs,$bxxs,$xxxs,$dqkcm,$dqjd);
//dd($cxjgs);
if(count($cxjgs) < 2){
echo '<center>'.$username.$cxjgs[0].'</center>';
JxgbxxModel::where('username', $username)->update(['JSESSIONID' => '','rizhi' => '无法获取未学的课程id,可能课程已学完']);//清空cookie文件重新登录
return view('home/jxgbxx/index',compact('username','password'));//跳转首页登录
}
$id = $cxjgs[0];//课程id
$zxs = $cxjgs[1];//总学时
$bxxs = $cxjgs[2];//必修学时
$xxxs = $cxjgs[3];//选修学时
$dqkcm = $cxjgs[4];//当前课程名
$dqjd = $cxjgs[5];//当前课程进度
//dd($cxjgs);
if ($name != '' && $id!= '' && $id!== '登录失败'){
JxgbxxModel::where('username', $username)->update(['zxs' => $zxs,'bxxs' => $bxxs,'xxxs' => $xxxs]);
unset($url);
unset($arr_header);//解决curl在循环体中只执行一次问题
//协议头是数组
$arr_header[] = "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
//首先需要访问http://www.jxgbwlxy.gov.cn/portal/study!start.action?id=59064130,让官网判断为在学习状态
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, "http://www.jxgbwlxy.gov.cn/portal/study!start.action?id=$id"); 
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch1, CURLOPT_CONNECTTIMEOUT, 10);//超时10秒中止访问,防止卡住
curl_setopt($ch1, CURLOPT_HTTPHEADER, $arr_header);//设置协议头
curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, 1);//阻止302重定向
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);//设置为0,只返回成功或失败,设置为1则返回网页源码
curl_setopt($ch1, CURLOPT_COOKIEFILE, $JSESSIONID);//读取cookie文件
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch1, CURLOPT_SSL_VERIFYHOST, false);
$token = curl_exec($ch1);
curl_close($ch1);
//dd($token);
if(strlen($token)!==32){
$rizhi = $oldrizhi.'--'.date('Y-m-d H:i:s').$username.'提交学习状态失败!';//追加日志
//更新数据库中的学习时长$xueshi和日志
echo $username.'提交学习状态失败!<br>';
JxgbxxModel::where('username', $username)->update(['rizhi' => $rizhi]);
break;
}
//post到官网更新时间
$url = "http://www.jxgbwlxy.gov.cn/student/course!addStudyDuration.action";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);//POST方式
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);//超时10秒中止访问,防止卡住
curl_setopt($ch, CURLOPT_HTTPHEADER, $arr_header);//设置协议头
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);//阻止302重定向
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置为0,只返回成功或失败,设置为1则返回网页源码
curl_setopt($ch, CURLOPT_POSTFIELDS, "id=$id");
curl_setopt($ch, CURLOPT_COOKIEFILE, $JSESSIONID);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$fanhui=curl_exec($ch);
//dd($fanhui);
if($fanhui == 'success' && $fanhui !== false){
$newrizhi = '--'.date('Y-m-d H:i:s').'学时增加5分钟';
}else{
$newrizhi = '--'.date('Y-m-d H:i:s').'学时增加0分钟';
}
//获取当前日志内容
$rizhi = $oldrizhi.$newrizhi;//追加日志
//更新数据库中的学习时长$xueshi和日志
JxgbxxModel::where('username', $username)->update(['rizhi' => $rizhi]);
}
curl_close($ch);
$cxjgs[] = $username;
$cxjgs[] = $name;
//dd($cxjgs);
return view('home/jxgbxx/yhmb2', compact('cxjgs'));//传递数组到查询用户面板视图
}
}
//获取已选的课程id
    public function getkcid($JSESSIONID)
{
$arr_header[] = "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
$i = 0;//避免死循环
do {
$url = "http://www.jxgbwlxy.gov.cn/student/course!list.action?course.course_type=0&init=yes";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);//超时10秒中止访问,防止卡住
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);//抓取跳转后数据
curl_setopt($ch, CURLOPT_HTTPHEADER, $arr_header);//设置协议头
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置为0,只返回成功或失败,设置为1则返回网页源码
curl_setopt($ch, CURLOPT_COOKIEFILE, $JSESSIONID); //读取cookie文件
curl_setopt($ch, CURLOPT_COOKIEJAR, $JSESSIONID);//保存新cookie到文件,防止超时掉线
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$content = curl_exec($ch);
$tqnr = $this->getSubstr($content,'学习进度','</table>');//已选的课程id,格式onclick="videoList(59129863);
$tqnr = preg_replace("/[\s]{2,}/","",$tqnr);//去除空格、制表符、换页符
$kcid = $this->getSubstr($tqnr,'userCourse.id=','&userCourse');//课程id
//dd($tqnr);
unset($url);//解决curl在循环体中只执行一次问题
$i++;
//如果重试5次都没有获取到课程id,则进入自动选课
if ($i >5){
/**
选课过程:
get获取课程courseId和assignId
POST1:http://www.jxgbwlxy.gov.cn/student/course!checkStudy.action ? courseId=3411&assignId=15
返回 userCourse.id=59166759
POST2:http://www.jxgbwlxy.gov.cn/student/course!isExits.action ? userCourse.id=59166759
返回1
POST3:http://www.jxgbwlxy.gov.cn/student/course!ajaxVideoList.action ? userCourse.id=59166759&select_year=undefined
返回1
**/
//get获取课程courseId和assignId
$arr_header[] = "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
$url1 = "http://www.jxgbwlxy.gov.cn/student/course!list.action?course.course_type=0&noStudy=1&init=yes&show_type=0";
$chxk = curl_init();
curl_setopt($chxk, CURLOPT_URL, $url1); 
curl_setopt($chxk, CURLOPT_HEADER, 0);
curl_setopt($chxk, CURLOPT_CONNECTTIMEOUT, 10);//超时10秒中止访问,防止卡住
curl_setopt($chxk, CURLOPT_HTTPHEADER, $arr_header);//设置协议头
curl_setopt($chxk, CURLOPT_FOLLOWLOCATION, 1);//阻止302重定向
curl_setopt($chxk, CURLOPT_RETURNTRANSFER, 1);//设置为0,只返回成功或失败,设置为1则返回网页源码
curl_setopt($chxk, CURLOPT_COOKIEFILE, $JSESSIONID);
curl_setopt($chxk, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($chxk, CURLOPT_SSL_VERIFYHOST, false);
$xknrs=curl_exec($chxk);
curl_close($chxk);
$xknrs = $this->getSubstr($xknrs,'课程显示方式','</table>');// <a target="_blank" href="/student/course!detail.action?type=0&course.id=3605&assignId=15"><b>焦裕禄</b></a>
$courseid = $this->getSubstr($xknrs,'&course.id=','&assignId');
$assignId= $this->getSubstr($xknrs,'&assignId=','">');
//POST1
unset($arr_header);//解决curl在循环体中只执行一次问题
$post1url = 'http://www.jxgbwlxy.gov.cn/student/course!checkStudy.action';
$arr_header[] = "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
$chget = curl_init();
curl_setopt($chget, CURLOPT_URL, $post1url); 
curl_setopt($chget, CURLOPT_HEADER, 0);
curl_setopt($chget, CURLOPT_POST, 1);//POST方式
curl_setopt($chget, CURLOPT_POSTFIELDS, "courseId=$courseid&assignId=$assignId&select_year=undefined");
curl_setopt($chget, CURLOPT_CONNECTTIMEOUT, 10);//超时10秒中止访问,防止卡住
curl_setopt($chget, CURLOPT_HTTPHEADER, $arr_header);//设置协议头
curl_setopt($chget, CURLOPT_FOLLOWLOCATION, 1);//阻止302重定向
curl_setopt($chget, CURLOPT_RETURNTRANSFER, 1);//设置为0,只返回成功或失败,设置为1则返回网页源码
curl_setopt($chget, CURLOPT_COOKIEFILE, $JSESSIONID);
curl_setopt($chget, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($chget, CURLOPT_SSL_VERIFYHOST, false);
$userCourseid=curl_exec($chget);
curl_close($chget);
//POST2
unset($arr_header);//解决curl在循环体中只执行一次问题
$post2url = 'http://www.jxgbwlxy.gov.cn/student/course!isExits.action';
$arr_header[] = "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
$chget = curl_init();
curl_setopt($chget, CURLOPT_URL, $post2url); 
curl_setopt($chget, CURLOPT_HEADER, 0);
curl_setopt($chget, CURLOPT_POST, 1);//POST方式
curl_setopt($chget, CURLOPT_POSTFIELDS, "userCourse.id=$userCourseid");
curl_setopt($chget, CURLOPT_CONNECTTIMEOUT, 10);//超时10秒中止访问,防止卡住
curl_setopt($chget, CURLOPT_HTTPHEADER, $arr_header);//设置协议头
curl_setopt($chget, CURLOPT_FOLLOWLOCATION, 1);//阻止302重定向
curl_setopt($chget, CURLOPT_RETURNTRANSFER, 1);//设置为0,只返回成功或失败,设置为1则返回网页源码
curl_setopt($chget, CURLOPT_COOKIEFILE, $JSESSIONID);
curl_setopt($chget, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($chget, CURLOPT_SSL_VERIFYHOST, false);
$fh=curl_exec($chget);
curl_close($chget);
//POST3
unset($arr_header);//解决curl在循环体中只执行一次问题
$post3url = 'http://www.jxgbwlxy.gov.cn/student/course!ajaxVideoList.action';
$arr_header[] = "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
$chget = curl_init();
curl_setopt($chget, CURLOPT_URL, $post3url); 
curl_setopt($chget, CURLOPT_HEADER, 0);
curl_setopt($chget, CURLOPT_POST, 1);//POST方式
curl_setopt($chget, CURLOPT_POSTFIELDS, "userCourse.id=$userCourseid&select_year=undefined");
curl_setopt($chget, CURLOPT_CONNECTTIMEOUT, 10);//超时10秒中止访问,防止卡住
curl_setopt($chget, CURLOPT_HTTPHEADER, $arr_header);//设置协议头
curl_setopt($chget, CURLOPT_FOLLOWLOCATION, 1);//阻止302重定向
curl_setopt($chget, CURLOPT_RETURNTRANSFER, 1);//设置为0,只返回成功或失败,设置为1则返回网页源码
curl_setopt($chget, CURLOPT_COOKIEFILE, $JSESSIONID);
curl_setopt($chget, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($chget, CURLOPT_SSL_VERIFYHOST, false);
$fhjg=curl_exec($chget);
curl_close($chget);
unset($arr_header);//解决curl在循环体中只执行一次问题
if ($fhjg !== '1'){
return array('课程id获取失败,请重新登录');
break;
}
}
}while ($kcid == '');
curl_close($ch);//循环体外关闭
$zxs = trim($this->getSubstr($content,'style="color: #30658d;">',"</span></div>"));//总学时
$bxxs = trim($this->getSubstr($content,"必修学时<span>","</span></div>"));//必修学时
$xxxs = trim($this->getSubstr($content,"选修学时<span>","</span></div>"));//选修学时
$dqkcm = trim($this->getSubstr($content,'全省必修课">',"</td>"));//当前课程名
$dqjd = trim($this->getSubstr($content,'margin-left: 5px;">',"</span>"));//当前课程进度
return array($kcid,$zxs,$bxxs,$xxxs,$dqkcm,$dqjd);
}
//取字符中间文字
public function getSubstr($str, $leftStr, $rightStr)
{
preg_match("|$leftStr([^^]*?)$rightStr|u", $str, $matches);
if (count($matches)>1){
return $matches[1];
}else{
//提取失败返回空
return '';
}
}
//取字符中间文字返回数组
public function getSubstrsz($str, $leftStr, $rightStr)
{
preg_match_all("|$leftStr([^^]*?)$rightStr|u", $str, $matches);
if (count($matches)>1){
return $matches[1];
}else{
//提取失败返回空数组
return array();
}
}
}

最后更新于:2019-10-30 12:25:30


上一篇: Laravel6.* 集成阿里云短信,发送验证码或其它信息(废弃)

下一篇: 又到期末放假时(小学篇)


  • 最新评论
  • 总共0条评论
需要登录才能发表评论

加入组织

  • QQ
  • 1. 手Q扫左侧二维码

    2. 搜Q群:617719749

    3. 点击加入学习群

最新评论