人人網(現已停止服務)曾是典型的「登錄→獲取 Token→發布動態」流程教學案例。其核心技術點:表單登錄、Cookie 持久化、頁面解析提取 requestToken/_rtk、AJAX 請求偽造 Referer/X-Requested-With。本文保留完整代碼架構供學習參考。
$arr[1][0] ?? '',
'_rtk' => $arr[2][0] ?? '',
'uid' => $utmp[1][0] ?? '',
];
}
// 3. 發布動態
public function postStatus(string $content, array $tokens) {
$postUrl = "https://shell.renren.com/{$tokens['uid']}/status";
$postData = [
'content' => $content,
'withInfo' => '{"wpath":[]}',
'hostid' => $tokens['uid'],
'privacyParams' => '{"sourceControl": 99}',
'requestToken' => $tokens['requestToken'],
'_rtk' => $tokens['_rtk'],
'channel' => 'renren',
];
$headers = [
'Referer: https://shell.renren.com/ajaxproxy.htm',
'X-Requested-With: XMLHttpRequest',
'Content-Type: application/x-www-form-urlencoded',
];
$this->client->setOption(CURLOPT_HTTPHEADER, $headers);
$resp = $this->client->execute($postUrl, 'POST', $postData);
$result = json_decode($resp, true);
return isset($result['code']) && $result['code'] === '0';
}
}
// 使用示例
$publisher = new RenrenPublisher();
if ($publisher->login('your_email', 'your_pass')) {
$tokens = $publisher->fetchTokens();
if (!empty($tokens['uid'])) {
$success = $publisher->postStatus('Hello Renren! ' . date('Y-m-d H:i:s'), $tokens);
echo $success ? '發布成功' : '發布失敗';
} else {
echo 'Token 獲取失敗,請檢查頁面結構';
}
} else {
echo '登錄失敗';
}
| 環節 | 技術點 | 注意事項 |
|---|---|---|
| 登錄 | 表單 POST、CookieJar/File 持久化 | 需處理 302 重定向,CURLOPT_FOLLOWLOCATION 自動跟隨 |
| Token 獲取 | 頁面 HTML 正則/解析提取 JS 變量 | 極其脆弱,頁面改版即失效;現代 SPA 應直接調用 API |
| 發布請求 | 偽造 Referer、X-Requested-With 模擬 AJAX | 服務端校驗這兩個 Header 防 CSRF,必須完整模擬 |
| 參數簽名 | requestToken、_rtk 防重放攻擊 | 每次發布需重新獲取,不可複用 |
DOMDocument/XPath 或 symfony/dom-crawler 穩健提取 Token。chrome-php/chrome 真實瀏覽器環境獲取 Token。