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 相关文章推荐
一个用于网络的工具函数库
Oct 09 PHP
mysql5写入和读出乱码解决
Nov 25 PHP
php 调用远程url的六种方法小结
Nov 02 PHP
php Smarty date_format [格式化时间日期]
Mar 15 PHP
PHP获取客户端真实IP地址的5种情况分析和实现代码
Jul 08 PHP
php实现用于计算执行时间的类实例
Apr 18 PHP
Symfony2使用Doctrine进行数据库查询方法实例总结
Mar 18 PHP
thinkPHP5.0框架命名空间详解
Mar 18 PHP
php实现用户登陆简单实例
Apr 04 PHP
PHP中OpenSSL加密问题整理
Dec 14 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
Nov 19 PHP
YII2框架中日志的配置与使用方法实例分析
Mar 18 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
BBS(php &amp; mysql)完整版(二)
2006/10/09 PHP
使用phpexcel类实现excel导入mysql数据库功能(实例代码)
2016/05/12 PHP
Nigma vs Alliance BO5 第二场2.14
2021/03/10 DOTA
javascript 用记忆函数快速计算递归函数
2010/03/15 Javascript
可插入图片的TEXT文本框
2013/12/27 Javascript
JavaScript实现的简单拖拽效果
2015/06/01 Javascript
json对象与数组以及转换成js对象的简单实现方法
2016/06/24 Javascript
基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询
2016/10/30 Javascript
AngularJS压缩JS技巧分析
2016/11/08 Javascript
JavaScript基于自定义函数判断变量类型的实现方法
2016/11/23 Javascript
JS中IP地址与整数相互转换的实现代码
2017/04/10 Javascript
微信小程序之滚动视图容器的实现方法
2017/09/26 Javascript
React BootStrap用户体验框架快速上手
2018/03/06 Javascript
详解vue数组遍历方法forEach和map的原理解析和实际应用
2018/11/15 Javascript
详解微信小程序胶囊按钮返回|首页自定义导航栏功能
2019/06/14 Javascript
jQuery实现input[type=file]多图预览上传删除等功能
2019/08/02 jQuery
laravel实现中文和英语互相切换的例子
2019/09/30 Javascript
利用PyInstaller将python程序.py转为.exe的方法详解
2017/05/03 Python
Python扩展内置类型详解
2018/03/26 Python
python实现list由于numpy array的转换
2018/04/04 Python
python traceback捕获并打印异常的方法
2018/08/31 Python
200行python代码实现贪吃蛇游戏
2020/04/24 Python
如何真正的了解python装饰器
2020/08/14 Python
python3 使用ssh隧道连接mysql的操作
2020/12/05 Python
MoviePy简介及Python视频剪辑自动化
2020/12/18 Python
python opencv肤色检测的实现示例
2020/12/21 Python
基于CSS3制作立体效果导航菜单
2016/01/12 HTML / CSS
英国家电购物网站:Sonic Direct
2019/03/26 全球购物
美国木工工具和用品商店:Woodcraft
2019/10/30 全球购物
学校元旦晚会方案
2014/02/19 职场文书
教师一帮一活动总结
2014/07/08 职场文书
建筑结构施工求职信
2014/07/11 职场文书
公司离职证明范本(5篇)
2014/09/17 职场文书
离婚撤诉申请书范本
2015/05/18 职场文书
地心历险记观后感
2015/06/15 职场文书
张丽莉事迹观后感
2015/06/16 职场文书