PHP多线程批量采集下载美女图片的实现代码(续)


Posted in PHP onJune 03, 2013

个人认为影响的原因:
匹配到的图片url并不是有效的url,文中只是简单的判断是否是相对路径,但是有些url是失效的
解决办法:就是新增判断是否是真实有效url的图片

/**
 * 
 *判断url是否有效 
 *@param $url string
 *@return boole 
 */
function relUrl($url){
 if(substr($url,0,4)=='http'){
  $array = get_headers($url,true);
  if(count($array)>0 && is_array($array)){
   if(preg_match('/200/', $array[0])){
    unset($array);
    return true;
   }else{
    unset($array);
    return false;
   }
  }else{
   unset($array);
   return false;
  }
 }else{
  return false;
 }
}

主要使用get_headers函数,获取http请求信息,判断服务端反应状态(200)判断url是否真实有效。

再次测试采集图片
结果比以前还要糟糕,运行的更慢了。

测试的原因就是:
get_headers函数虽然可以判断url是否真实有效,但是假如遇到很慢的url资源,因为get-heades请求没有时间限制,导致这个线程被占用,后续的请求被阻塞
file_get_content函数和上面的原因一样,由于某些慢的url资源都长期占用,阻塞后面的进程被占用,长期阻塞,cpu占用也会增高
解决办法;
使用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"."<br/>";
   }else{
    unset($kk,$vv);
   }
  }
 }else{
  unset($matches);
 }
}
$etime = $img->getMicrotime();//结束时间
echo "用时".($etime-$stime)."秒";
exit;

测试一下效果
PHP多线程批量采集下载美女图片的实现代码(续)
337张图片用时260秒左右,基本上可以做到一秒内就可以采集一张的效果,而且发现图片越到优势采集速度越明显。

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

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

PHP 相关文章推荐
对squid中refresh_pattern的一些理解和建议
Apr 17 PHP
PHP包含文件函数include、include_once、require、require_once区别总结
Apr 05 PHP
PHP间隔一段时间执行代码的方法
Dec 02 PHP
PHP使用in_array函数检查数组中是否存在某个值
Mar 25 PHP
PHP+MySQL之Insert Into数据插入用法分析
Sep 27 PHP
php生成高清缩略图实例详解
Dec 07 PHP
php获取ip及网址的简单方法(必看)
Apr 01 PHP
PHP实现生成推广海报的方法详解
Mar 14 PHP
php empty 函数判断结果为空但实际值却为非空的原因解析
May 28 PHP
微信公众号之主动给用户发送消息功能
Jun 22 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
Feb 23 PHP
浅析PHP中json_encode与json_decode的区别
Jul 15 PHP
获取php页面执行时间,数据库读写次数,函数调用次数等(THINKphp)
Jun 03 #PHP
php变量作用域的深入解析
Jun 03 #PHP
CURL的学习和应用(附多线程实现)
Jun 03 #PHP
php魔术方法与魔术变量、内置方法与内置变量的深入分析
Jun 03 #PHP
PHP flush()与ob_flush()的区别详解
Jun 03 #PHP
PHP导出EXCEL快速开发指南--PHPEXCEL的使用详解
Jun 03 #PHP
PHP Cookie的使用教程详解
Jun 03 #PHP
You might like
PHP中::、-&amp;gt;、self、$this几种操作符的区别介绍
2013/04/24 PHP
apache php mysql开发环境安装教程
2016/07/28 PHP
[原创]php集成安装包wampserver修改密码后phpmyadmin无法登陆的解决方法
2016/11/23 PHP
PHP基于curl模拟post提交json数据示例
2018/06/22 PHP
使用JavaScript实现网页版Pongo设计思路及源代码分享
2014/06/16 Javascript
jQuery动画与特效详解
2015/02/01 Javascript
javascript实现表单提交后,提交按钮不可用的方法
2015/04/18 Javascript
javascript格式化指定日期对象的方法
2015/04/21 Javascript
JavaScript中的Math.atan2()方法使用详解
2015/06/15 Javascript
DIV+CSS+jQ实现省市联动可扩展
2016/06/22 Javascript
浅谈angularJS中的事件
2016/07/12 Javascript
js仿京东轮播效果 选项卡套选项卡使用
2017/01/12 Javascript
Webpack+Vue如何导入Jquery和Jquery的第三方插件
2017/02/20 Javascript
详解微信小程序 登录获取unionid
2017/06/27 Javascript
如何使用JS在HTML中自定义字符串格式化
2017/07/20 Javascript
JS实现点击链接切换显示隐藏内容的方法
2017/10/19 Javascript
ES6 javascript的异步操作实例详解
2017/10/30 Javascript
Node.js API详解之 util模块用法实例分析
2020/05/09 Javascript
Vue中nprogress页面加载进度条的方法实现
2020/11/13 Javascript
零基础写python爬虫之urllib2中的两个重要概念:Openers和Handlers
2014/11/05 Python
python获取指定路径下所有指定后缀文件的方法
2015/05/26 Python
Python socket编程实例详解
2015/05/27 Python
python编写微信公众号首图思路详解
2019/12/13 Python
使用keras时input_shape的维度表示问题说明
2020/06/29 Python
使用pandas实现筛选出指定列值所对应的行
2020/12/13 Python
纯css3实现的鼠标悬停动画按钮
2014/12/23 HTML / CSS
HTML5 video播放器全屏(fullScreen)方法实例
2015/04/24 HTML / CSS
如何避免常见的6种HTML5错误用法
2017/11/06 HTML / CSS
localStorage、sessionStorage使用总结
2017/11/17 HTML / CSS
周年庆典邀请函范文
2014/01/23 职场文书
家具商场的活动方案
2014/08/16 职场文书
课外访万家心得体会
2014/09/03 职场文书
先进人物事迹材料
2014/12/29 职场文书
2015年小学校长工作总结
2015/05/19 职场文书
公司员工宿舍管理制度
2015/08/07 职场文书
Ajax常用封装库——Axios的使用
2021/05/08 Javascript