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

PHP cURL 抓取 AJAX 異步加載內容實戰

     編輯:PHP 相關知識

現代網頁大量採用 AJAX 異步載入數據,**直接抓取首頁 HTML 只能得到空容器或 JS 代碼**。正確姿勢:使用瀏覽器開發者工具(Network 面板)定位真實 API 接口、請求參數、Header,然後用 cURL 模擬該請求獲取結構化數據(通常為 JSON)。

定位 AJAX 接口四步法

  1. 打開目標頁面,按 F12 開啟開發者工具 → Network 面板。
  2. 勾選 XHR / Fetch 過濾器,刷新頁面或觸發交互。
  3. 點擊目標請求,查看 Headers(URL、Method、Request Headers)、Payload(POST 參數)、Response(返回數據格式)。
  4. 右鍵 → Copy → Copy as cURL (bash) 可直接獲得命令列參考。

實戰案例:抓取某門戶新聞列表

目標頁:https://www.example.com/news/list,列表數據由 JS 異步載入。

1. 分析 Network 請求

Request URL: https://www.example.com/api/news/list
Request Method: POST
Request Headers:
  Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  X-Requested-With: XMLHttpRequest
  Referer: https://www.example.com/news/list
  Cookie: PHPSESSID=abc123; user_trace_id=xyz
Form Data:
  page: 1
  page_size: 20
  category_id: 101
  _token: csrf_token_here
Response (JSON):
  { "code": 0, "data": { "list": [...], "total": 1500 } }

2. PHP cURL 模擬代碼

<?php
function fetchNewsList(int $page = 1, int $pageSize = 20, int $categoryId = 101): ?array {
    $url = 'https://www.example.com/api/news/list';
    
    // 必須攜帶的 Header(模擬瀏覽器 AJAX 特徵)
    $headers = [
        'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
        'X-Requested-With: XMLHttpRequest',
        'Referer: https://www.example.com/news/list',
        'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        // 'Cookie: PHPSESSID=abc123; user_trace_id=xyz', // 若需登錄態
    ];
    
    $postData = http_build_query([
        'page' => $page,
        'page_size' => $pageSize,
        'category_id' => $categoryId,
        // '_token' => getCsrfToken(), // 若有 CSRF 需先獲取
    ]);
    
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => $url,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $postData,
        CURLOPT_HTTPHEADER     => $headers,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_ENCODING       => 'gzip, deflate', // 自動解壓
    ]);
    
    $response = curl_exec($ch);
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    curl_close($ch);
    
    if ($errno !== CURLE_OK) {
        error_log("cURL Error [$errno]: $error");
        return null;
    }
    
    $data = json_decode($response, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        error_log("JSON Decode Error: " . json_last_error_msg());
        return null;
    }
    
    return $data['data']['list'] ?? [];
}

// 使用
$news = fetchNewsList(1, 20, 101);
foreach ($news as $item) {
    echo $item['title'] . PHP_EOL;
}
?>

進階:處理動態 Token / 簽名 / 加密參數

  • CSRF Token:先抓取頁面 HTML,正則/解析器提取 <meta name="csrf-token"> 或表單隱藏字段,再帶入 API 請求。
  • 簽名算法:部分 API 要求參數按鍵名排序拼接 + 密鑰 MD5/HMAC。需逆向 JS 代碼或抓包分析規律,PHP 端複製實現。
  • 加密參數:如 encrypt(data, publicKey)。選項:① PHP 端用 OpenSSL 實現同算法;② 嵌入 V8JS/QuickJS 執行原 JS;③ 改用 Headless Chrome (Puppeteer/PHP-WebDriver)。

Cookie 持久化會話(模擬登錄後抓取)

<?php
$cookieJar = sys_get_temp_dir() . '/cookies_' . md5($domain) . '.txt';

// 1. 登錄獲取 Cookie
$ch = curl_init('https://example.com/login');
curl_setopt_array($ch, [
    CURLOPT_POST       => true,
    CURLOPT_POSTFIELDS => ['username' => $user, 'password' => $pass],
    CURLOPT_COOKIEJAR  => $cookieJar, // 保存 Cookie
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
curl_close($ch);

// 2. 後續請求攜帶 Cookie
$ch = curl_init('https://example.com/api/private/data');
curl_setopt_array($ch, [
    CURLOPT_COOKIEFILE => $cookieJar, // 讀取 Cookie
    CURLOPT_RETURNTRANSFER => true,
]);
$data = curl_exec($ch);
curl_close($ch);
?>

反爬蟲應對清單

策略應對
User-Agent 檢測設置真實瀏覽器 UA,輪換池
Referer/Origin 檢測設置正確 Referer、Origin
請求頻率限制隨機延遲、IP 代理池、分散式爬蟲
JS 生成簽名/Token逆向算法、V8JS、Headless Chrome
字體加密/圖形驗證碼OCR 識別、字體映射表、打碼平台
行為分析(鼠標軌跡、點擊)Headless Chrome + 模擬操作

法律與道德提醒

  • 遵守 robots.txt、網站服務條款 (ToS)。
  • 控制抓取頻率,不影響目標服務器正常運行。
  • 僅抓取公開數據,不繞過登錄/付費牆、不侵犯用戶隱私。
  • 商業用途請尋求官方 API 或數據授權。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved