【问题标题】:Download multiple images from remote server with PHP (a LOT of images)使用 PHP 从远程服务器下载多个图像(大量图像)
【发布时间】:2013-03-04 09:39:47
【问题描述】:

我正在尝试从外部服务器下载大量文件(大约 3700 张图像)。这些图像每个大小从 30KB 到 200KB。

当我在 1 张图片上使用 copy() 函数时,它可以工作。当我循环使用它时,我得到的只是 30B 图像(空图像文件)。

我尝试使用 copycURLwgetfile_get_contents。每次,我要么得到很多空文件,要么什么都没有。

这是我尝试过的代码:

wget:

exec('wget http://mediaserver.centris.ca/media.ashx?id=ADD4B9DD110633DDDB2C5A2D10&t=pi&f=I -O SIA/8605283.jpg');

复制:

if(copy($donnees['PhotoURL'], $filetocheck)) {
  echo 'Photo '.$filetocheck.' updated<br/>';
}

卷曲:

$ch = curl_init();
$source = $data[PhotoURL];
curl_setopt($ch, CURLOPT_URL, $source);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec ($ch);
curl_close ($ch);

$destination = $newfile;
$file = fopen($destination, "w+");
fputs($file, $data);
fclose($file);

似乎没有任何工作正常。不幸的是,我没有太多选择一次下载所有这些文件,我需要一种方法让它尽快工作。

非常感谢,安托万

【问题讨论】:

  • 他们可能会阻止像这样的大量下载。尝试询问服务器/服务的管理员。
  • 这可能是有道理的,但是这个服务器是为这样的大量下载而设计的,它是一个我自己去获取图像的系统,而不是他们必须通过 FTP 将它们发送给我。

标签: php curl upload copy


【解决方案1】:

逐一获取它们可能会很慢。考虑将它们分成 20-50 个图像的包并用多个线程抓取它们。这是帮助您入门的代码:

$chs = array();
$cmh = curl_multi_init();
for ($t = 0; $t < $tc; $t++)
{
    $chs[$t] = curl_init();
    curl_setopt($chs[$t], CURLOPT_URL, $targets[$t]);
    curl_setopt($chs[$t], CURLOPT_RETURNTRANSFER, 1);
    curl_multi_add_handle($cmh, $chs[$t]);    
}

$running=null;
do {
    curl_multi_exec($cmh, $running);
} while ($running > 0);

for ($t = 0; $t < $tc; $t++)
{
    $path_to_file = 'your logic for file path';
    file_put_contents($path_to_file, curl_multi_getcontent($chs[$t]));
    curl_multi_remove_handle($cmh, $chs[$t]);
    curl_close($chs[$t]);
}
curl_multi_close($cmh);

我最近使用这种方法抓取了几百万张图片,因为一张一张需要长达一个月的时间。

您一次抓取的图像数量应取决于它们的预期大小和您的内存限制。

【讨论】:

    【解决方案2】:

    我为此使用了这个功能并且效果很好。

    function saveImage($urlImage, $title){
    
        $fullpath = '../destination/'.$title;
        $ch = curl_init ($urlImage);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
        $rawdata=curl_exec($ch);
        curl_close ($ch);
        if(file_exists($fullpath)){
            unlink($fullpath);
        }
        $fp = fopen($fullpath,'x');
        $r = fwrite($fp, $rawdata);
    
        setMemoryLimit($fullpath);
    
        fclose($fp);
    
        return $r;
    }
    

    结合这个防止内存溢出:

    function setMemoryLimit($filename){
       set_time_limit(50);
       $maxMemoryUsage = 258;
       $width  = 0;
       $height = 0;
       $size   = ini_get('memory_limit');
    
       list($width, $height) = getimagesize($filename);
       $size = $size + floor(($width * $height * 4 * 1.5 + 1048576) / 1048576);
    
       if ($size > $maxMemoryUsage) $size = $maxMemoryUsage;
    
       ini_set('memory_limit',$size.'M');
    
    }
    

    【讨论】:

    • 一开始没用,现在好像可以了。使用变量“fullpath”,我使用了“/home/mls/public_html...”,这显然是错误的。非常感谢,我现在可以下载图片了,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多