php多線程採集網頁的解決辦法 curl多線程採集

既然爲了學習,那麼先來了解下PHP curl函數信息:php

PHP cURL全部函數列表:https://secure.php.net/manual/zh/ref.curl.phphtml

如下是PHP中cURL多線程相關函數:

  • curl_multi_add_handle — 向curl批處理會話中添加單獨的curl句柄
  • curl_multi_close — 關閉一組cURL句柄
  • curl_multi_exec — 運行當前 cURL 句柄的子鏈接
  • curl_multi_getcontent — 若是設置了CURLOPT_RETURNTRANSFER,則返回獲取的輸出的文本流
  • curl_multi_info_read — 獲取當前解析的cURL的相關傳輸信息
  • curl_multi_init — 返回一個新cURL批處理句柄
  • curl_multi_remove_handle — 移除curl批處理句柄資源中的某個句柄資源
  • curl_multi_select — 等待全部cURL批處理中的活動鏈接
  • curl_multi_setopt — 爲 cURL 並行處理設置一個選項
  • curl_multi_strerror — Return string describing error code

通常來講,想到要用這些函數時,目的顯然應該是要同時請求多個URL,而不是一個一個依次請求,不然不如本身循環去調curl_exec好了。算法

步驟總結以下:

一、調用 curl_multi_init,初始化一個批處理handle數組

二、循環調用 curl_multi_add_handle,往1中的批處理handle 添加curl_init來的子handle多線程

三、持續調用 curl_multi_exec,直到全部子handle執行完畢。curl

四、根據須要循環調用 curl_multi_getcontent 獲取結果ide

五、調用 curl_multi_remove_handle,併爲每一個字handle調用curl_close函數

六、調用 curl_multi_closepost

好了,直接上函數(輸入參數爲url數組,返回結果爲對應的網頁源碼數組)學習

function curl_multi($urls) {
        if (!is_array($urls) or count($urls) == 0) {
            return false;
        }
        $num=count($urls);
        $curl = $curl2 = $text = array();
        $handle = curl_multi_init();
        function createCh($url) {
            $ch = curl_init();
            curl_setopt ($ch, CURLOPT_URL, $url);
            curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko');//設置頭部
            curl_setopt ($ch, CURLOPT_REFERER, $url); //設置來源
            curl_setopt ($ch, CURLOPT_ENCODING, "gzip"); // 編碼壓縮
            curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);//是否採集30一、302以後的頁面
            curl_setopt ($ch, CURLOPT_MAXREDIRS, 5);//查找次數,防止查找太深
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 對認證證書來源的檢查
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 從證書中檢查SSL加密算法是否存在
            curl_setopt ($ch, CURLOPT_TIMEOUT, 20);
            curl_setopt ($ch, CURLOPT_HEADER, 0);//輸出頭部
            return $ch;
        }
        foreach($urls as $k=>$v){
            $url=$urls[$k];
            $curl[$k] = createCh($url);
            curl_multi_add_handle ($handle,$curl[$k]);
        }
        $active = null;
        do {
            $mrc = curl_multi_exec($handle, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
 
        while ($active && $mrc == CURLM_OK) {
            if (curl_multi_select($handle) != -1) {
                usleep(100);
            }
            do {
                $mrc = curl_multi_exec($handle, $active);
            } while ($mrc == CURLM_CALL_MULTI_PERFORM);
        }
 
        foreach ($curl as $k => $v) {
            if (curl_error($curl[$k]) == "") {
                $text[$k] = (string) curl_multi_getcontent($curl[$k]);
            }
            curl_multi_remove_handle($handle, $curl[$k]);
            curl_close($curl[$k]);
        }
        curl_multi_close($handle);
        return $text;
    }

調取測試
 

$urls = [];
for($i=1;$i<=46;$i++){
	$url ="https://www.xx.com/play/61804-1-$i.html";
	$urls[$i]= $url;
}

$res=curl_multi($urls);
print_r($res);

速度提高了很多

相關文章
相關標籤/搜索