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

PHP cURL 模擬登錄帶驗證碼網站:Cookie 持久化、驗證碼識別、Session 維持完整實現

     編輯:PHP 相關知識

PHP cURL 模擬登錄帶驗證碼網站完整實現

針對帶驗證碼的登錄頁面,實現自動獲取驗證碼圖片、用戶輸入驗證碼、攜帶 Cookie 發起登錄請求、解析響應判斷結果、登錄後持久化 Cookie 訪問受保護頁面的完整流程。代碼基於 ThinkPHP 3.x 控制器結構,邏輯通用可移植。

核心類結構

class LoginController extends Controller {
    protected $cookieName = ['cookie_verify', 'cookie_verify'];
    protected $cookiePath = '/cookie/';
    protected $cookiePathFile = [];

    public function _initialize() {
        foreach ($this->cookieName as $key => $name) {
            $this->cookiePathFile[] = ROOT_PATH . $this->cookiePath . $name . '_xxx.txt';
        }
    }
    // ...

1. 獲取驗證碼圖片

public function getVerifyCode() {
    $img = $this->_cookieRequest('https://xxx.com/VerifyCode_Login.aspx?id=' . rand(10000, 999999), null, true, 1);
    echo $img; // 直接輸出圖片二進制流
}

前端 <img src="/login/getVerifyCode" onclick="this.src=this.src+'&t='+Math.random()"> 實現點擊刷新。

2. 登錄提交處理

public function xxxLogin() {
    $username = I('username');
    $password = I('password');
    $verifyCode = I('verify');

    $loginData = array(
        '__VIEWSTATE' => '/wEPDwUKMTU0MzAzOTU4NmQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFDExvZ2luX1N1Ym1pdL/yae69NsY163G3yuP0lxjz8oXu',
        '__VIEWSTATEGENERATOR' => 'DC42DE27',
        'txt_UserName' => $username,
        'txt_PWD' => $password,
        'txt_VerifyCode' => $verifyCode,
        'SMONEY' => 'ABC',
        'Login_Submit.x' => '52',
        'Login_Submit.y' => '19',
    );

    $getBack = $this->_cookieRequest('https://xxx.com/noLogin.aspx', $loginData);

    // 解析錯誤提示
    if (preg_match('/<div[^<div]*?id\s*=\s*[\'"]{1}div_msg[\'"]{1}.*?>(.*?)<\/div>/s', $getBack, $match)) {
        // 頁面包含錯誤 div
    } else {
        // 解析重定向 URL 參數判斷具體錯誤碼
        $paramsFull = parse_url($getBack);
        parse_str($paramsFull['query'], $paramsFull['parsedQuery']);
        if (!empty($paramsFull['parsedQuery']['Warn'])) {
            $msgMap = [
                2 => '驗證碼錯誤', 3 => '帳號不存在', 5 => '賬戶已注銷',
                6 => '密碼錯誤', 20 => '今日密碼錯誤3次', 21 => 'IP密碼錯誤9次',
                22 => 'IP登錄帳號過多', 23 => '驗證碼失效', 32 => '帳號綁定衝突', 33 => '一天只能註冊一個'
            ];
            $this->error($msgMap[$paramsFull['parsedQuery']['Warn']] ?? '登錄失敗');
        } else {
            $_SESSION['user_id'] = '123456';
            $this->success('登錄成功', U('Index/index'));
        }
    }
}

3. 核心 cURL 封裝 _cookieRequest

private function _cookieRequest($url, $data = null, $redirect = false, $cookieNum = 0) {
    $ch = curl_init();
    $params = [
        CURLOPT_URL => $url,
        CURLOPT_HEADER => false,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1',
    ];

    if ($data) {
        $params[CURLOPT_POST] = true;
        $params[CURLOPT_POSTFIELDS] = http_build_query($data);
    }

    // Cookie 管理:優先讀取現有文件,否則創建新文件
    if (!empty($_COOKIE[$this->cookieName[$cookieNum]]) && is_file($this->cookiePathFile[$cookieNum])) {
        $params[CURLOPT_COOKIEFILE] = $this->cookiePathFile[$cookieNum];
    } else {
        $params[CURLOPT_COOKIEJAR] = $this->cookiePathFile[$cookieNum];
        setcookie($this->cookieName[$cookieNum], $this->cookiePathFile[$cookieNum], time() + 120);
    }

    curl_setopt_array($ch, $params);
    $content = curl_exec($ch);
    $headers = curl_getinfo($ch);
    curl_close($ch);

    if ($url != $headers["url"] && !$redirect) {
        return $headers["url"]; // 返回重定向地址
    }
    return $content;
}

關鍵技術點

  1. Cookie 持久化:CURLOPT_COOKIEJAR (寫入) + CURLOPT_COOKIEFILE (讀取) 配合文件存儲,跨請求保持會話
  2. 驗證碼處理:單獨接口輸出圖片流,前端 img 標籤加載,用戶肉眼識別輸入
  3. ViewState 等隱藏字段:ASP.NET 頁面必須攜帶 __VIEWSTATE、__VIEWSTATEGENERATOR 等字段
  4. 錯誤碼映射:解析重定向 URL 參數 Warn 映射友好提示
  5. User-Agent 偽裝:模擬真實瀏覽器降低風控攔截

登錄後複用

登錄成功後,_cookieRequest 可直接用於訪問其他需認證頁面,自動攜帶已保存 Cookie。

擴展建議

  • 接入 OCR API (百度/騰訊/阿里) 實現驗證碼自動識別,實現全自動化
  • 增加請求頻率限制、IP 代理池應對反爬蟲
  • 使用 GuzzleHttp 替代原生 cURL,代碼更現代化
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved