首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 模擬登入方正教務系統:繞過驗證碼、CURL 維持 Session 並解析課表

     編輯:PHP 相關知識

PHP 模擬登入方正教務系統:繞過驗證碼、CURL 維持 Session 並解析課表

方正教務系統(正方)存在一處驗證碼邏輯缺口:若不請求驗證碼圖片,後端不生成驗證碼 Session,提交空驗證碼即可通過。結合 CURL 維持 Cookie,可實現自動登入並抓取課表、空教室等資料。

核心 CURL 封裝

<?php
function curl_request($url, $post = [], $cookie = '', $returnCookie = 0) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
    curl_setopt($ch, CURLOPT_REFERER, 'https://jw.example.com/default2.aspx'); // 必須為登入頁
    curl_setopt($ch, CURLOPT_TIMEOUT, 20);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

    if ($post) {
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
    }
    if ($cookie) {
        curl_setopt($ch, CURLOPT_COOKIE, $cookie);
    }
    if ($returnCookie) {
        curl_setopt($ch, CURLOPT_HEADER, 1);
    }

    $data = curl_exec($ch);
    if (curl_errno($ch)) return curl_error($ch);
    curl_close($ch);

    if ($returnCookie) {
        list($header, $body) = explode("\r\n\r\n", $data, 2);
        preg_match_all('/Set-Cookie:([^;]*);/', $header, $matches);
        return ['cookie' => substr($matches[1][0], 1), 'content' => $body];
    }
    return $data;
}
?>

登入流程

  1. 取得 __VIEWSTATE:請求登入頁,正則提取隱藏欄位
  2. 提交登入表單:包含 __VIEWSTATE、學號、密碼、空驗證碼、語言、角色、登入按鈕
  3. 解析 Set-Cookie:取得 ASP.NET_SessionId 後續請求攜帶
<?php
function getViewState($url) {
    $html = curl_request($url);
    preg_match('//', $html, $m);
    return $m[1] ?? '';
}

function login($username, $password) {
    $url = 'https://jw.example.com/default2.aspx';
    $post = [
        '__VIEWSTATE' => getViewState($url),
        'txtUserName' => $username,
        'TextBox2' => $password,
        'txtSecretCode' => '', // 空驗證碼
        'RadioButtonList1' => iconv('UTF-8', 'GB2312', '學生'),
        'Button1' => iconv('UTF-8', 'GB2312', '登錄'),
    ];
    return curl_request($url, $post, '', true)['cookie'];
}
?>

抓取課表並轉二維陣列

<?php
function fetchSchedule($username, $password) {
    $cookie = login($username, $password);
    $viewState = getViewStateWithCookie("https://jw.example.com/xskbcx.aspx?xh=$username", $cookie);

    $url = "https://jw.example.com/xskbcx.aspx?xh=$username";
    $html = curl_request($url, [], $cookie);

    // 解析 Table#Table1
    preg_match('/]*>(.*?)<\/table>/s', $html, $tableMatch);
    $tableHtml = $tableMatch[1] ?? '';

    preg_match_all('/]*>(.*?)<\/td>/s', $tableHtml, $tdMatch);
    $cells = $tdMatch[1];

    // 清理 
、HTML 實體、轉編碼 foreach ($cells as &$c) { $c = iconv('GB2312', 'UTF-8', strip_tags(str_replace('
', '', $c))); } // 轉結構化陣列:['周一'=>['1,2'=>'課程名', ...], ...] $schedule = []; $days = ['周日','周一','周二','周三','周四','周五','周六']; $periods = ['1,2','3,4','5,6','7,8','9,10']; // ... 解析邏輯略 return $schedule; } ?>

空教室查詢

需提交 xxjsjy.aspx 表單,包含 __VIEWSTATE、學年、學期、星期、節次、校區等欄位,解析回傳表格。

關鍵技術點總結

  • 編碼轉換:系統為 GB2312,PHP 為 UTF-8,所有 POST 欄位與回應皆需 iconv
  • 隱藏欄位動態更新:每次請求前重新取得 __VIEWSTATE
  • Cookie 持久化:登入後取得 Cookie 後續所有請求帶上
  • 防封鎖:加入隨機 User-Agent、請求間隔、IP 代理池

法律與道德提醒

僅供學術研究與個人便利使用,請勿大規模爬取、洩露他人隱私或影響系統穩定,遵守學校資訊安全規定。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved