模擬登錄 QQ 空間並抓取訪客記錄涉及複雜的登錄協議、加密算法、Cookie 管理、多步驟請求鏈。本文從架構層面解析核心模組,不提供完整可運行代碼(涉及逆向工程風險),而是通用技術方案教學。
| 環節 | 技術挑戰 | 通用解決思路 |
|---|---|---|
| 登錄協議 | 多步驟跳轉、JS 加密、驗證碼、設備指紋 | 抓包分析請求鏈,還原關鍵參數生成邏輯 |
| 密碼加密 | 雙層 MD5 + RSA + 驗證碼鹽值 | 移植 JS 加密函數至 PHP (v8js/ExecJS) 或純 PHP 實現 |
| GTK 算法 | skey → g_tk 簽名參數 | 移植官方 JS 算法 (DJB2 雜湊變體) |
| Cookie 管理 | 跨域、HttpOnly、多子域共享 | cURL CookieJar 文件持久化、域匹配規則 |
| 反爬策略 | IP 限流、行為分析、JS 混淆、環境檢測 | 代理池、請求間隔隨機化、Headless 瀏覽器 |
// 核心類結構
class QQZoneVisitor {
// 1. HTTP 客戶端層:封裝 cURL、Cookie、Header、代理、重試
private HttpClient $http;
// 2. 協議層:登錄流程、參數構建、響應解析
private LoginProtocol $login;
private VisitorApi $visitorApi;
// 3. 加密層:GTK、密碼加密、簽名算法
private Crypto $crypto;
// 4. 存儲層:Cookie 文件、配置、訪客數據緩存
private Storage $storage;
// 5. 調度層:定時任務、錯誤重試、賬號輪換
private Scheduler $scheduler;
}
class HttpClient {
private $ch;
private $cookieFile;
public function __construct(string $cookieFile) {
$this->cookieFile = $cookieFile;
$this->initCurl();
}
private function initCurl() {
$this->ch = curl_init();
curl_setopt_array($this->ch, [
CURLOPT_COOKIEJAR => $this->cookieFile,
CURLOPT_COOKIEFILE => $this->cookieFile,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true, // 需解析 Set-Cookie
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_TIMEOUT => 20,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_USERAGENT => 'Mozilla/5.0 ...',
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 10,
]);
}
public function request(string $url, array $options = []): Response {
// 合并默認選項、執行、解析 Header/Body、錯誤處理
// 返回結構化 Response 對象
}
}
class Crypto {
// DJB2 雜湊變體:hash = hash * 33 + char_code
public static function getGTK(string $skey): int {
$hash = 5381;
for ($i = 0, $len = strlen($skey); $i < $len; $i++) {
$hash += ($hash << 5) + ord($skey[$i]);
}
return $hash & 0x7FFFFFFF; // 2147483647
}
// 密碼加密:MD5(MD5(pass) + uin) + vcode
public static function getEncryption(string $password, string $uin, string $vcode): string {
$str1 = pack('H*', strtoupper(md5($password))); // 十六進制轉二進制
$str2 = strtoupper(md5($str1 . $uin));
return strtoupper(md5($str2 . strtoupper($vcode)));
}
}
login_sig, pt_qzone_sig, appid 等隱藏參數check.ptlogin2.qq.com/check 判斷是否需驗證碼ptlogin2.qq.com/loginptsig、重定向 URLptsig 訪問 user.qzone.qq.com 獲取核心 JS 配置skey 計算 g_tk,後續 API 必需class VisitorApi {
public function getVisitors(string $uin, int $g_tk, int $page = 1): array {
$url = 'https://g.qzone.qq.com/cgi-bin/friendshow/cgi_get_visitor_more';
$params = [
'uin' => $uin,
'mask' => 7,
'g_tk' => $g_tk,
'page' => $page,
'fupdate' => 1,
'clear' => 1,
'sd' => microtime(true) * 1000,
];
$response = $this->http->get($url, ['query' => $params]);
// 解析 JSONP 響應:_Callback({...})
return $this->parseJsonp($response->getBody());
}
}
crontab / Swoole Timer / Laravel Scheduler,配合鎖防止重複執行uin+visitor_uin,增量同步| 方案 | 優勢 | 劣勢 | 適用場景 |
|---|---|---|---|
| cURL + 協議逆向 | 輕量、可控、無瀏覽器開銷 | 維護成本高、易失效、法律風險 | 內部監控、授權數據同步 |
| Headless Chrome (Puppeteer/Playwright) | 真實瀏覽器環境、自動執行 JS、繞過大部分檢測 | 資源重、啟動慢、難以大規模並發 | 複雜登錄、動態渲染頁面 |
| 官方 Open API | 合法、穩定、文檔完善 | 權限受限、數據字段少、需審核 | 合規業務、公開數據獲取 |
技術無善惡,使用者有責任。掌握 cURL 協議模擬、加密移植、反爬對抗等核心能力,應用於合法授權的系統集成與數據互通場景。