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

PHP cURL 模擬登入 Discuz! 論壇並自動發帖完整教學

     編輯:PHP 相關知識

適用場景

  • 自動化測試、資料同步、內容分發
  • Discuz! X 系列 (X3.4/X3.5 等)
  • 需處理 formhash、Cookie、驗證碼、安全提問

核心流程

  1. 取得登入頁 formhash
  2. POST 登入表單,攜帶 Cookie Jar
  3. 進入發帖頁,取得發帖 formhash
  4. POST 發帖內容,附帶 Cookie 與 Referer
  5. 清理暫存 Cookie 檔案

完整實戰代碼

<?php
$discuzUrl = 'https://www.example.com/';      // 論壇首頁 (必須 HTTPS)
$loginUrl  = $discuzUrl . 'member.php?mod=logging&action=login&loginsubmit=yes&infloat=yes&lssubmit=yes&inajax=1';
$postUrl   = $discuzUrl . 'forum.php?mod=post&action=newthread&fid=2&extra=page%3D1'; // fid=版塊 ID

$cookieFile = sys_get_temp_dir() . '/dz_cookie_' . uniqid() . '.txt';

// --- 步驟 1: 取得登入 formhash ---
$ch = curl_init($loginUrl);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_COOKIEJAR      => $cookieFile,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_USERAGENT      => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
]);
$html = curl_exec($ch);
curl_close($ch);

if (preg_match('/name="formhash" value="([^"]+)"/', $html, $m)) {
    $loginFormhash = $m[1];
} else {
    die('無法取得登入 formhash');
}

// --- 步驟 2: 提交登入 ---
$postFields = [
    'formhash'        => $loginFormhash,
    'referer'         => $discuzUrl,
    'loginfield'      => 'username',
    'username'        => 'your_username',
    'password'        => 'your_password',
    'questionid'      => 0,        // 安全提問 ID (0=無)
    'answer'          => '',       // 安全提問答案
    'seccodeverify'   => '',       // 驗證碼 (若開啟需額外識別)
    'loginsubmit'     => 'true',
];

$ch = curl_init($loginUrl);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query($postFields),
    CURLOPT_COOKIEJAR      => $cookieFile,
    CURLOPT_COOKIEFILE     => $cookieFile,
    CURLOPT_REFERER        => $loginUrl,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_USERAGENT      => 'Mozilla/5.0...',
]);
$html = curl_exec($ch);
curl_close($ch);

// 簡易判斷登入成功
if (strpos($html, 'succeed') === false && strpos($html, '歡迎您歸來') === false) {
    die('登入失敗: ' . strip_tags($html));
}
echo "登入成功\n";

// --- 步驟 3: 取得發帖 formhash ---
$ch = curl_init($postUrl);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_COOKIEFILE     => $cookieFile,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_USERAGENT      => 'Mozilla/5.0...',
]);
$html = curl_exec($ch);
curl_close($ch);

// 發帖頁 formhash 通常在 
if (preg_match('/name="formhash" id="formhash" value="([^"]+)"/', $html, $m)) {
    $postFormhash = $m[1];
} else {
    die('無法取得發帖 formhash');
}

// --- 步驟 4: 提交發帖 ---
$postData = [
    'formhash'      => $postFormhash,
    'subject'       => '測試標題 ' . date('H:i:s'),
    'message'       => '這是 cURL 自動發帖測試內容。',
    'topicsubmit'   => 'yes',
    'tags'          => '測試,自動化,PHP',
    'typeid'        => 0,        // 分類 ID (可選)
    'save'          => '',       // 草稿箱
];

$ch = curl_init($postUrl);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => http_build_query($postData),
    CURLOPT_COOKIEFILE     => $cookieFile,
    CURLOPT_REFERER        => $postUrl,   // 關鍵:防跨站提交檢查
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_USERAGENT      => 'Mozilla/5.0...',
]);
$html = curl_exec($ch);
curl_close($ch);

if (strpos($html, 'succeed') !== false || strpos($html, '發帖成功') !== false) {
    echo "發帖成功!\n";
} else {
    echo "發帖失敗: " . strip_tags($html) . "\n";
}

// --- 步驟 5: 清理 ---
@unlink($cookieFile);

關鍵技術點解析

環節關鍵點
formhashDiscuz 防 CSRF 核心,每個表單唯一,必須動態抓取,不可硬編碼
Cookie 管理使用 CURLOPT_COOKIEJAR (寫入) + CURLOPT_COOKIEFILE (讀取) 維持會話
Referer發帖時必須設定 CURLOPT_REFERER 為發帖頁 URL,否則被判定「來路不正確」
User-Agent模擬真實瀏覽器,避免被防火牆攔截
HTTPS現代論壇強制 HTTPS,需 CURLOPT_SSL_VERIFYPEER => true (生產環境)
驗證碼若開啟驗證碼,需整合 OCR 或第三方打碼平台 (超出本文範圍)
安全提問若帳號設有安全提問,需在登入表單帶入 questionid 和 answer

常見問題排查

  • 登入成功但發帖失敗「來路不正確」:Referer 未設定或錯誤,必須設為發帖頁完整 URL。
  • formhash 正則匹配失敗:頁面結構可能不同,使用瀏覽器開發者工具檢查實際 HTML,調整正則。
  • Cookie 檔案權限問題:確保 PHP 進程對暫存目錄有讀寫權限。
  • 雲端防火牆 (Cloudflare/WAF):可能返回 5 秒盾或驗證頁,需整合 curl_cloudflare 或使用 Selenium/Playwright 真實瀏覽器自動化。
  • 編碼問題:確保腳本檔案為 UTF-8,Discuz 為 UTF-8 版本,http_build_query 自動處理 URL 編碼。

法律與道德提醒

⚠️ 僅供授權測試、自有站點維護、學習研究使用。 未經許可自動化操作他人網站可能違反《計算機信息網絡國際聯網安全保護管理辦法》、網站服務條款,甚至構成非法侵入計算機信息系統罪。請遵守 robots.txt、API 協議、爬蟲禮儀,控制請求頻率,不濫用資源。

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