江西干部网站学院老版自动学习PHP源码
2019-10-27 admin laravel 1587
江西干部网站学院网站已经改版,页面美观了许多,后台逻辑也更加完善了,这个版本的源码已不能正常使用,仅写下来研究学习原理。
实现目标:用户登录后,将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 ""; }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 ""; }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,'',""));//姓名 $zxs = trim($this->getSubstr($content,'style="color: #30658d;">',"
'; 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,'学习进度','');//已选的课程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,'课程显示方式','');// 焦裕禄 $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;">',""));//总学时 $bxxs = trim($this->getSubstr($content,"必修学时",""));//必修学时 $xxxs = trim($this->getSubstr($content,"选修学时",""));//选修学时 $dqkcm = trim($this->getSubstr($content,'全省必修课">',""));//当前课程名 $dqjd = trim($this->getSubstr($content,'margin-left: 5px;">',""));//当前课程进度 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(); } } }