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 相关文章推荐
Get或Post提交值的非法数据处理
Oct 09 PHP
模拟OICQ的实现思路和核心程序(三)
Oct 09 PHP
PHP一些有意思的小区别
Dec 06 PHP
php字符串截取中文截取2,单字节截取模式
Dec 10 PHP
Memcache 在PHP中的使用技巧
Feb 08 PHP
PHP支持多种格式图片上传(支持jpg、png、gif)
Nov 03 PHP
浅析SVN常见问题及解决方法
Jun 21 PHP
thinkPHP模型初始化实例分析
Dec 03 PHP
thinkphp自带验证码全面解析
Sep 18 PHP
PHP 根据key 给二维数组分组
Dec 09 PHP
PHP简单实现循环链表功能示例
Nov 10 PHP
PHP面向对象五大原则之单一职责原则(SRP)详解
Apr 04 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(3) php 函数
2010/02/15 PHP
PHP异常Parse error: syntax error, unexpected T_VAR错误解决方法
2014/05/06 PHP
php实现信用卡校验位算法THE LUHN MOD-10示例
2014/05/07 PHP
查找php配置文件php.ini所在路径的二种方法
2014/05/26 PHP
php继承中方法重载(覆盖)的应用场合
2015/02/09 PHP
PHP通过CURL实现定时任务的图片抓取功能示例
2016/10/03 PHP
基于jquery用于查询操作的实现代码
2010/05/10 Javascript
说说JSON和JSONP 也许你会豁然开朗
2012/09/02 Javascript
javascript计算用户打开网页的停留时间
2014/01/09 Javascript
jQuery获取和设置表单元素的方法
2014/02/14 Javascript
JavaScript DSL 流畅接口(使用链式调用)实例
2015/03/15 Javascript
jquery实现不包含当前项的选择器实例
2015/06/25 Javascript
JS简单封装的图片无缝滚动效果示例【测试可用】
2017/03/22 Javascript
微信小程序本地缓存数据增删改查实例详解
2017/05/24 Javascript
JavaScript表单即时验证 验证不成功不能提交
2017/08/31 Javascript
详解JavaScript修改注册表的方法
2020/01/05 Javascript
[03:40]DOTA2英雄梦之声_第01期_炼金术士
2014/06/23 DOTA
[00:32]2018DOTA2亚洲邀请赛EG出场
2018/04/03 DOTA
Go语言基于Socket编写服务器端与客户端通信的实例
2016/02/19 Python
网红编程语言Python将纳入高考你怎么看?
2018/06/07 Python
python实现批量修改图片格式和尺寸
2018/06/07 Python
详解Python 协程的详细用法使用和例子
2018/06/15 Python
python3.6中@property装饰器的使用方法示例
2019/08/17 Python
使用Pycharm在运行过程中,查看每个变量的操作(show variables)
2020/06/08 Python
Python钉钉报警及Zabbix集成钉钉报警的示例代码
2020/08/17 Python
Canon佳能美国官方商店:购买数码相机、数码单反相机、镜头和打印机
2016/11/15 全球购物
女性时尚网购:Chic Me
2019/07/30 全球购物
php优化查询foreach代码实例讲解
2021/03/24 PHP
个人自我鉴定怎么写
2013/10/28 职场文书
实习单位推荐信范文
2013/11/27 职场文书
公司培训欢迎词
2014/01/10 职场文书
《伯牙绝弦》教学反思
2014/03/02 职场文书
法人代表授权委托书
2014/04/08 职场文书
幼儿园中班下学期评语
2014/04/18 职场文书
贯彻落实“八项规定”思想汇报
2014/09/13 职场文书
单位接收函范文
2015/01/30 职场文书