使用file_get_content系列函数和使用curl系列函数采集图片的性能对比

  由于公司的一个汽车网站的后台的汽车内容都是主要是来自与汽车之家的,编辑的同事们必须天天手动去对着汽车之家来添加汽车,实在是太蛋疼了。于是乎,为了改变这种状况,作为一个开发码农,我的任务就来了。。。那就是准备做一个功能,只要粘贴对应的汽车之家的网址url就能对这些数据进行自动填充到我们后台的表单中,目前基本的填充都实现了,但是还是没有能够把对应的汽车相册采集进来。

  采集图片的功能我以前也做过,但是汽车之家大部分的汽车都有挺多图片的,开始的时候,我打算使用以前的采集图片的办法,也就是使用file_get_content获取url对应的内容,然后匹配到图片的地址,再使用file_get_content获取这些图片url的内容,再载入到本地去,代码如下:

<?php
header(‘Content-type:text/html;charset=utf-8‘);
set_time_limit(0);

class runtime  
{  
    var $StartTime = 0;  
    var $StopTime = 0;  
   
    function get_microtime()  
    {  
        list($usec, $sec) = explode(‘ ‘, microtime());  
        return ((float)$usec + (float)$sec);  
    }  
   
    function start()  
    {  
        $this->StartTime = $this->get_microtime();  
    }  
   
    function stop()  
    {  
        $this->StopTime = $this->get_microtime();  
    }  
   
    function spent()  
    {  
        return round(($this->StopTime - $this->StartTime) * 1000, 1);  
    }  
   
}  

$runtime= new runtime();  
$runtime->start();  

$url = ‘http://car.autohome.com.cn/pic/series-s15306/289.html#pvareaid=102177‘;
$rs = file_get_contents($url);
// echo $rs;exit;
preg_match_all(‘/(\/pic\/series-s15306\/289-\d+\.html)/‘, $rs, $urlArr);

$avalie = array_unique($urlArr[0]);
$count = array();
foreach ($avalie as $key => $ul) {
   $pattern = ‘/<img src="(http:\/\/car1\.autoimg\.cn\/upload\/\d+\/\d+\/\d+\/.*?\.jpg)"/‘;
   preg_match_all($pattern, file_get_contents(‘http://car.autohome.com.cn‘.$ul), $imgSrc);
   $count = array_merge($count, $imgSrc[1]);
}


foreach($count as $k=>$v) {
  $data[$k] = file_get_contents($v);
}

foreach($data as $k=>$v) {
  file_put_contents(‘./pic2/‘.time().‘_‘.rand(1, 10000).‘.jpg‘, $v);
}

$runtime->stop();  
echo "页面执行时间: ".$runtime->spent()." 毫秒"; 

  结果发现,这种方法少图片还好,图片多了,那是相当的卡。。就本地测试也比较难跑,更不如说到时候上线了。百度之后,我采用了curl的办法来下载图片,经过测试后的确有所改善,但是感觉还是有点慢,要是php有多线程那有多好。。。

  又经过一番折腾和找资料,发现php的curl库其实还是可以模拟多线程的,那就是使用curl_multi_*系列的函数,经过改写,代码又变成了这样:

  

<?php
header(‘Content-type:text/html;charset=utf-8‘);
set_time_limit(0);

class runtime  
{  
    var $StartTime = 0;  
    var $StopTime = 0;  
   
    function get_microtime()  
    {  
        list($usec, $sec) = explode(‘ ‘, microtime());  
        return ((float)$usec + (float)$sec);  
    }  
   
    function start()  
    {  
        $this->StartTime = $this->get_microtime();  
    }  
   
    function stop()  
    {  
        $this->StopTime = $this->get_microtime();  
    }  
   
    function spent()  
    {  
        return round(($this->StopTime - $this->StartTime) * 1000, 1);  
    }  
   
}  

$runtime= new runtime();  
$runtime->start();  


$url = ‘http://car.autohome.com.cn/pic/series-s15306/289.html#pvareaid=102177‘;
$rs = file_get_contents($url);
preg_match_all(‘/(\/pic\/series-s15306\/289-\d+\.html)/‘, $rs, $urlArr);

$avalie = array_unique($urlArr[0]);
$count = array();
foreach ($avalie as $key => $ul) {
   $pattern = ‘/<img src="(http:\/\/car1\.autoimg\.cn\/upload\/\d+\/\d+\/\d+\/.*?\.jpg)"/‘;
   preg_match_all($pattern, file_get_contents(‘http://car.autohome.com.cn‘.$ul), $imgSrc);
   $count = array_merge($count, $imgSrc[1]);
}

$handle = curl_multi_init();

foreach($count as $k => $v) {
  $curl[$k] = curl_init($v);
  curl_setopt($curl[$k], CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($curl[$k], CURLOPT_HEADER, 0);
  curl_setopt($curl[$k], CURLOPT_TIMEOUT, 30);
  curl_multi_add_handle ($handle, $curl[$k]);
}

$active = null;

do {
    $mrc = curl_multi_exec($handle, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    // 这句在php5.3以后的版本很关键,因为没有这句,可能curl_multi_select可能会永远返回-1,这样就永远死在循环里了
    while (curl_multi_exec($handle, $active) === CURLM_CALL_MULTI_PERFORM);

    if (curl_multi_select($handle) != -1) {
        do {
            $mrc = curl_multi_exec($handle, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

foreach ($curl as $k => $v) {
    if (curl_error($curl[$k]) == "") {
        $data[$k] = curl_multi_getcontent($curl[$k]);
    }
    curl_multi_remove_handle($handle, $curl[$k]);
    curl_close($curl[$k]);
}

foreach($data as $k=>$v) {
    $file = time().‘_‘.rand(1000, 9999).‘.jpg‘;
    file_put_contents(‘./pic3/‘.$file, $v); 
}

curl_multi_close($handle);

$runtime->stop();  
echo "页面执行时间: ".$runtime->spent()." 毫秒"; 

  好了,多线程的采集真是非常酸爽,然后通过一系列的测试和对比,5次测试,curl多线程有4次是快于file_get_content的,而且时间还是file_get_content的3~5倍,总结起来,以后采集都尽量使用这种办法,提高效率不在话下。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。