php curl 防止采集,php多线程采集网页的解决办法 curl多线程采集
一直在使用thinkphp做項目,同樣也經常進行采集!而對于物聯卡來說,就更要大量的采集運營商提供的API信息,平時使用PHP單線程curl采集多個網頁的時候速度特別慢,尤其是采集幾十個接口的時候(電信不提供多個流量卡同時調用數據的接口,只能一個一個的查詢);這個速度慢的要死要死的!于是就想到curl多線程采集的問題,最終找到幾個效果還是很不錯的!解決了采集運營商接口的大難題!測試了一下,采集20條數據的時間為4秒左右,比平時要快2倍了!
既然為了學習,那么先來了解下PHP curl函數信息:
以下是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好了。
步驟總結如下:
1、調用 curl_multi_init,初始化一個批處理handle
2、循環調用 curl_multi_add_handle,往1中的批處理handle 添加curl_init來的子handle
3、持續調用 curl_multi_exec,直到所有子handle執行完畢。
5、調用 curl_multi_remove_handle,并為每個字handle調用curl_close
好了,直接上函數(輸入參數為url數組,返回結果為對應的網頁源碼數組)
PHP
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);//是否采集301、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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
functioncurl_multi($urls){
if(!is_array($urls)orcount($urls)==0){
returnfalse;
}
$num=count($urls);
$curl=$curl2=$text=array();
$handle=curl_multi_init();
functioncreateCh($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);//是否采集301、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($urlsas$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($curlas$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;
}
函數使用:
PHP
$urls=array('http://www.21863.cn',
'http://www.baidu.com',
'http://www.baidu.com',
'http://blog.21863.cn',
'http://www.baidu.com',
'http://www.baidu.com',
'http://www.baidu.com',
'http://www.baidu.com'
);
$res=curl_multi($urls);
print_r($res);
1
2
3
4
5
6
7
8
9
10
11
$urls=array('http://www.21863.cn',
'http://www.baidu.com',
'http://www.baidu.com',
'http://blog.21863.cn',
'http://www.baidu.com',
'http://www.baidu.com',
'http://www.baidu.com',
'http://www.baidu.com'
);
$res=curl_multi($urls);
print_r($res);
而這個多線程的采集函數怎么運用到實際的項目中,這就很簡單了吧!
總結
以上是生活随笔為你收集整理的php curl 防止采集,php多线程采集网页的解决办法 curl多线程采集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php动态生成链接,PHP动态生成jav
- 下一篇: php如何防止超发,PHP+redis实