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

PHP 利用 cURL 多執行緒並發抓取網頁實戰指南

     編輯:PHP 相關知識

PHP 利用 cURL 多執行緒並發抓取網頁實戰指南

PHP 本身不支援原生多執行緒,但透過 cURL Multi 介面 可實現並發非阻塞請求,大幅提升爬蟲、API 聚合等場景的吞吐量。本文提供兩種完整實作範例:直接寫入檔案與先存變數再處理。

核心概念

  • curl_multi_init():建立多執行緒控制代碼
  • curl_multi_add_handle():將單一 cURL handle 加入多執行緒批次
  • curl_multi_exec():執行批次請求,需在迴圈中反覆呼叫直到所有完成
  • curl_multi_getcontent():取得個別請求的回應內容

範例一:直接將抓取內容寫入檔案

適合大量資料直接落地存儲,記憶體佔用極低。

<?php
$urls = array(
    'https://www.sina.com.cn/',
    'https://www.sohu.com/',
    'https://www.163.com/'
);
$save_to = '/test.txt';
$fp = fopen($save_to, "a");

$mh = curl_multi_init();
foreach ($urls as $i => $url) {
    $conn[$i] = curl_init($url);
    curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
    curl_setopt($conn[$i], CURLOPT_HEADER, 0);
    curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT, 60);
    curl_setopt($conn[$i], CURLOPT_FILE, $fp); // 直接寫入檔案指標
    curl_multi_add_handle($mh, $conn[$i]);
}

$active = null;
do {
    curl_multi_exec($mh, $active);
} while ($active);

// 清理資源
foreach ($urls as $i => $url) {
    curl_multi_remove_handle($mh, $conn[$i]);
    curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($fp);
?>

範例二:先取得內容字串,再寫入檔案(或入庫)

適合需要對回應資料進行後處理(如解析、過濾、入資料庫)的場景。

<?php
$urls = array(
    'https://www.sina.com.cn/',
    'https://www.sohu.com/',
    'https://www.163.com/'
);
$save_to = '/test.txt';
$fp = fopen($save_to, "a");

$mh = curl_multi_init();
foreach ($urls as $i => $url) {
    $conn[$i] = curl_init($url);
    curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
    curl_setopt($conn[$i], CURLOPT_HEADER, 0);
    curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT, 60);
    curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, true); // 關鍵:回傳字串而非直接輸出
    curl_multi_add_handle($mh, $conn[$i]);
}

$active = null;
do {
    curl_multi_exec($mh, $active);
} while ($active);

// 取得各請求結果並處理
foreach ($urls as $i => $url) {
    $data = curl_multi_getcontent($conn[$i]);
    fwrite($fp, $data); // 這裡可改為 DB 寫入、JSON 解析等
}

// 清理
foreach ($urls as $i => $url) {
    curl_multi_remove_handle($mh, $conn[$i]);
    curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($fp);
?>

進階建議

  1. 錯誤處理:使用 curl_error() 檢查個別 handle 錯誤,配合 curl_multi_info_read() 獲取完成請求的詳細資訊。
  2. 並發數控制:生產環境建議限制同時連線數(如 10-20),避免對目標伺服器造成過大壓力或觸發防火牆封禁。
  3. 超時設定:合理設定 CURLOPT_CONNECTTIMEOUT 與 CURLOPT_TIMEOUT,防止殭屍連線佔用資源。
  4. 非阻塞事件驅動:高併發場景可考慮 Swoole、Workerman 或 ReactPHP 等擴展,效能更優。

掌握 cURL Multi,讓 PHP 也能輕鬆應對高併發網路請求場景。

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