2010-01-09 6 views
21

Uzak bir dosyayı cURL ile kısmen indirmek mümkün mü? Diyelim ki, uzak dosyanın gerçek dosya boyutu 1000 KB'dir. Sadece ilk 500 KB'yi nasıl indirebilirim?Uzak bir dosyayı cURL ile kısmen nasıl indirebilirim?

+0

: https://unix.stackexchange.com/questions/121314/download-only-a-part-of-a-file Doğru, ancak bu her zaman güvenilir değildir ve bağlı olduğu bulunmuştur –

cevap

34

olduğunu.

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, 'http://www.spiegel.de/'); 
curl_setopt($ch, CURLOPT_RANGE, '0-500'); 
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$result = curl_exec($ch); 
curl_close($ch); 
echo $result; 

Ama sunucu bu başlığı onurlandırmak ama bütün dosya bukle hepsini indirir gönderir yoksa daha önce belirtildiği gibi

. Örneğin. http://www.php.net, başlığı yok sayar. Ancak (ek olarak) bir yazma fonksiyonu geri çağrısı belirleyebilir ve daha fazla veri alındığında talebi iptal edebilirsiniz (ör.

// php 5.3+ only 
// use function writefn($ch, $chunk) { ... } for earlier versions 
$writefn = function($ch, $chunk) { 
    static $data=''; 
    static $limit = 500; // 500 bytes, it's only a test 

    $len = strlen($data) + strlen($chunk); 
    if ($len >= $limit) { 
    $data .= substr($chunk, 0, $limit-strlen($data)); 
    echo strlen($data) , ' ', $data; 
    return -1; 
    } 

    $data .= $chunk; 
    return strlen($chunk); 
}; 

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, 'http://www.php.net/'); 
curl_setopt($ch, CURLOPT_RANGE, '0-500'); 
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $writefn); 
$result = curl_exec($ch); 
curl_close($ch); 
+0

+1. Bu, $ writefn(), sınıra ulaşıldığında -1 döndürdüğü için çalışır. Geri arama işlevi, kendisine iletilen bayt sayısı dışında bir şey döndürdüğünde ($ yığın), curl bağlantıyı iptal eder. – GZipp

+0

Mükemmel. Perl'de aynı şeyi yaptığımda, daha iyi bir yöntemin olmaması için dosya boyutu için tetiklenen ve kontrol edilen bir alarm kullanmak zorunda kaldım. Çok hacky ama işe yaradı. –

+0

Sadece ihtiyacım olan şey. Bununla birlikte, bahsetmeye değer de 'yığın' boyutunu tanımlayan CURLOPT_BUFFERSIZE'dır. Tamponunuz çok büyükse, yığın boyutu zaten her türlü veriyi kolaylıkla içerebilir (sanırım! –

17

bir belgenin ilk 100 bayt alın: Eğer bu (indirme çözüm olabilir

+3

sunucu üzerinde ve kendini kıvırmak değil. Hatalı durumlarda, curl sadece indirmeye devam ederdi. –

+0

Farklı bir aralık kullandığımda, örneğin 100-200’leri indiremiyorum. "Kıvrılma hatası (18)" alıyorum. Bu çözülebilir mi? İyi cevap için – akashrajkn

0

modern curl olduğundan emin olun

curl -r 0-99 http://www.get.this 

manuel

den ilk 500KB içine output.txt)

curl -r 0-511999 http://www.yourwebsite.com > output.txt 
  • 511999 ederken Ayrıca php-bukle uzantılı aralık başlığı parametresini ayarlayabilirsiniz 500^1024-1
0

Hoş bir çözüm VolkerK için teşekkürler. Ancak bu kodu bir işlev olarak kullanmam gerekti, işte bu yüzden geldim. Umarım başkaları için yararlıdır. Ana fark, kullanımı ($ limit, & $ datadump), dolayısıyla bir sınır geçilebilir ve sonuç olarak döndürmek için by-reference değişken $ datadump kullanılarak. Bazı web siteleri bir kullanıcı aracı üstbilgisi olmadan erişime izin vermeyeceği için CURLOPT_USERAGENT adresini de ekledim.

Kontrol http://php.net/manual/en/functions.anonymous.php

function curl_get_contents_partial($url, $limit) { 
    $writefn = function($ch, $chunk) use ($limit, &$datadump) { 
    static $data = ''; 

    $len = strlen($data) + strlen($chunk); 
    if ($len >= $limit) { 
     $data .= substr($chunk, 0, $limit - strlen($data)); 
     $datadump = $data; 
     return -1; 
    } 
    $data .= $chunk; 
    return strlen($chunk); 
    }; 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13'); 
    //curl_setopt($ch, CURLOPT_RANGE, '0-1000'); //not honored by many sites, maybe just remove it altogether. 
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_WRITEFUNCTION, $writefn); 
    $data = curl_exec($ch); 
    curl_close($ch); 
    return $datadump; 
} 

kullanımı:
$ page = curl_get_contents_partial ('http://some.webpage.com', 1000); // ilk 1000 baytlık
echo $ page // sayfasını okuyun ya da sonuçla ne yaparsanız yapın. başlıklarını kullanarak