php多线程批量采集下载图片
?
使用curl的多线程,另外curl可以设置请求时间,遇到很慢的url资源,可以果断的放弃,这样没有阻塞,另外有多线程请求,效率应该比较高,参考:《curl的学习和应用[附多线程]》,我们再来测试一下;
核心代码:
?
/** * curl 多线程 * * @param array $array 并行网址 * @param int $timeout 超时时间 * @return mix */ public function curl_http($array,$timeout='15'){ $res = array(); $mh = curl_multi_init();//创建多个curl语柄 foreach($array as $k=>$url){ $conn[$k]=curl_init($url);//初始化 curl_setopt($conn[$k], curlopt_timeout, $timeout);//设置超时时间 curl_setopt($conn[$k], curlopt_useragent, 'mozilla/5.0 (compatible; msie 5.01; windows nt 5.0)'); curl_setopt($conn[$k], curlopt_maxredirs, 7);//http定向级别 ,7最高 curl_setopt($conn[$k], curlopt_header, false);//这里不要header,加块效率 curl_setopt($conn[$k], curlopt_followlocation, 1); // 302 redirect curl_setopt($conn[$k], curlopt_returntransfer,1);//要求结果为字符串且输出到屏幕上 curl_setopt($conn[$k], curlopt_httpget, true); curl_multi_add_handle ($mh,$conn[$k]); } //防止死循环耗死cpu 这段是根据网上的写法 do { $mrc = curl_multi_exec($mh,$active);//当无数据,active=true } while ($mrc == curlm_call_multi_perform);//当正在接受数据时 while ($active and $mrc == curlm_ok) {//当无数据时或请求暂停时,active=true if (curl_multi_select($mh) != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == curlm_call_multi_perform); } } foreach ($array as $k => $url) { if(!curl_errno($conn[$k])){ $data[$k]=curl_multi_getcontent($conn[$k]);//数据转换为array $header[$k]=curl_getinfo($conn[$k]);//返回http头信息 curl_close($conn[$k]);//关闭语柄 curl_multi_remove_handle($mh , $conn[$k]); //释放资源 }else{ unset($k,$url); } } curl_multi_close($mh); return $data; }//参数接收$callback = $_get['callback'];$hrefs = $_get['hrefs'];$urlarray = explode(',',trim($hrefs,','));$date = date('ymd',time());//实例化$img = new httpimg();$stime = $img->getmicrotime();//开始时间$data = $img->curl_http($urlarray,'20');//列表数据mkdir('./img/'.$date,0777);foreach ((array)$data as $k=>$v){ preg_match_all(/(href|src)=([\|']?)([^ \'>]+\.(jpg|png|png|jpg|gif))\\2/i, $v, $matches[$k]); if(count($matches[$k][3])>0){ $dataimg = $img->curl_http($matches[$k][3],'20');//全部图片数据二进制 $j = 0; foreach ((array)$dataimg as $kk=>$vv){ if($vv !=''){ $rand = rand(1000,9999); $basename = time()._.$rand...jpg;//保存为jpg格式的文件 $fname = './img/'.$date./.$basename; file_put_contents($fname, $vv); $j++; echo 创建第.$j.张图片.$fname.
; }else{ unset($kk,$vv); } } }else{ unset($matches); }}$etime = $img->getmicrotime();//结束时间echo 用时.($etime-$stime).秒;exit;
?
?
测试一下效果337张图片用时260秒左右,基本上可以做到一秒内就可以采集一张的效果,而且发现图片越到优势采集速度越明显。
我们可以看一下文件命名:也就可以做到同一时刻可以生成10张图片,
由于采用了20秒请求的时间限制,有些图片生成后有明显不全,也就是图片资源在20秒内未能完全采集,这个时间大家可以自行设置。
?