PHP多线程批量采集下载图片

来源:互联网 发布:smb端口 编辑:程序博客网 时间:2024/05/22 08:28

PHP多线程批量采集下载图片

    博客分类:
  • PHP
 

 

使用curl的多线程,另外curl可以设置请求时间,遇到很慢的url资源,可以果断的放弃,这样没有阻塞,另外有多线程请求,效率应该比较高,参考:《CURL的学习和应用[附多线程]》,我们再来测试一下;

核心代码:

 

Php代码  收藏代码
  1. /** 
  2.      * curl 多线程 
  3.      * 
  4.      * @param array $array 并行网址 
  5.      * @param int $timeout 超时时间 
  6.      * @return mix 
  7.      */  
  8.     public function Curl_http($array,$timeout='15'){  
  9.             $res = array();  
  10.   
  11.             $mh = curl_multi_init();//创建多个curl语柄  
  12.   
  13.             foreach($array as $k=>$url){  
  14.                 $conn[$k]=curl_init($url);//初始化  
  15.   
  16.                 curl_setopt($conn[$k], CURLOPT_TIMEOUT, $timeout);//设置超时时间  
  17.                 curl_setopt($conn[$k], CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');  
  18.                 curl_setopt($conn[$k], CURLOPT_MAXREDIRS, 7);//HTTp定向级别 ,7最高  
  19.                 curl_setopt($conn[$k], CURLOPT_HEADER, false);//这里不要header,加块效率  
  20.                 curl_setopt($conn[$k], CURLOPT_FOLLOWLOCATION, 1); // 302 redirect  
  21.                 curl_setopt($conn[$k], CURLOPT_RETURNTRANSFER,1);//要求结果为字符串且输出到屏幕上  
  22.                 curl_setopt($conn[$k], CURLOPT_HTTPGET, true);  
  23.   
  24.                 curl_multi_add_handle ($mh,$conn[$k]);  
  25.             }  
  26.              //防止死循环耗死cpu 这段是根据网上的写法  
  27.                 do {  
  28.                     $mrc = curl_multi_exec($mh,$active);//当无数据,active=true  
  29.                 } while ($mrc == CURLM_CALL_MULTI_PERFORM);//当正在接受数据时  
  30.                 while ($active and $mrc == CURLM_OK) {//当无数据时或请求暂停时,active=true  
  31.                     if (curl_multi_select($mh) != -1) {  
  32.                         do {  
  33.                             $mrc = curl_multi_exec($mh$active);  
  34.                         } while ($mrc == CURLM_CALL_MULTI_PERFORM);  
  35.                     }  
  36.                 }  
  37.   
  38.             foreach ($array as $k => $url) {  
  39.                   if(!curl_errno($conn[$k])){  
  40.                     $data[$k]=curl_multi_getcontent($conn[$k]);//数据转换为array  
  41.                     $header[$k]=curl_getinfo($conn[$k]);//返回http头信息  
  42.                     curl_close($conn[$k]);//关闭语柄  
  43.                     curl_multi_remove_handle($mh  , $conn[$k]);   //释放资源  
  44.                   }else{  
  45.                     unset($k,$url);  
  46.                   }  
  47.                 }  
  48.   
  49.                 curl_multi_close($mh);  
  50.   
  51.                 return $data;  
  52.   
  53.          }  
  54.   
  55. //参数接收  
  56. $callback = $_GET['callback'];  
  57. $hrefs = $_GET['hrefs'];  
  58. $urlarray = explode(',',trim($hrefs,','));  
  59. $date = date('Ymd',time());  
  60. //实例化  
  61. $img = new HttpImg();  
  62. $stime = $img->getMicrotime();//开始时间  
  63.   
  64. $data = $img->Curl_http($urlarray,'20');//列表数据  
  65. mkdir('./img/'.$date,0777);  
  66. foreach ((array)$data as $k=>$v){  
  67.     preg_match_all("/(href|src)=([\"|']?)([^ \"'>]+\.(jpg|png|PNG|JPG|gif))\\2/i"$v$matches[$k]);  
  68.   
  69.     if(count($matches[$k][3])>0){  
  70.         $dataimg = $img->Curl_http($matches[$k][3],'20');//全部图片数据二进制  
  71.         $j = 0;  
  72.         foreach ((array)$dataimg as $kk=>$vv){  
  73.             if($vv !=''){  
  74.                 $rand = rand(1000,9999);  
  75.                 $basename = time()."_".$rand.".".jpg;//保存为jpg格式的文件  
  76.                 $fname = './img/'.$date."/"."$basename";  
  77.                 file_put_contents($fname$vv);  
  78.                 $j++;  
  79.                 echo "创建第".$j."张图片"."$fname"."<br/>";  
  80.             }else{  
  81.                 unset($kk,$vv);  
  82.             }  
  83.         }  
  84.     }else{  
  85.         unset($matches);  
  86.     }  
  87. }  
  88. $etime = $img->getMicrotime();//结束时间  
  89. echo "用时".($etime-$stime)."秒";  
  90. exit;  

 

 

测试一下效果

337张图片用时260秒左右,基本上可以做到一秒内就可以采集一张的效果,而且发现图片越到优势采集速度越明显。

image我们可以看一下文件命名:也就可以做到同一时刻可以生成10张图片,

由于采用了20秒请求的时间限制,有些图片生成后有明显不全,也就是图片资源在20秒内未能完全采集,这个时间大家可以自行设置。