2010-01-09 6 views
21

Ist es möglich, eine Remote-Datei mit cURL teilweise herunterzuladen? Nehmen wir an, die tatsächliche Dateigröße der Remote-Datei beträgt 1000 KB. Wie kann ich nur die ersten 500 KB herunterladen?Wie eine Remote-Datei mit cURL teilweise herunterladen?

+0

Header verwenden: https://unix.stackexchange.com/questions/121314/download-only-a-part-of-a-file –

Antwort

34

Sie können auch den Bereich Header-Parameter mit der php-curl Erweiterung gesetzt.

Aber wie bereits erwähnt, wenn der Server diesen Header nicht honoriert, aber die ganze Datei curl sendet, wird alles heruntergeladen. Z.B. http://www.php.net ignoriert die Kopfzeile. Sie können jedoch (zusätzlich) einen Schreibfunktionsrückruf einstellen und die Anforderung abbrechen, wenn mehr Daten empfangen werden, z.

// 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 für eine gute Antwort. Dies funktioniert, weil $ writefn() -1 zurückgibt, wenn das Limit erreicht ist. Wenn die Callback-Funktion einen anderen Wert als die Anzahl der übergebenen Bytes (in $ chunk) zurückgibt, bricht curl die Verbindung ab. – GZipp

+0

Ausgezeichnet. Als ich das gleiche in Perl machte, musste ich einen Alarm verwenden, der ausgelöst und auf die Dateigröße überprüft wurde, weil es keine bessere Methode gab. Sehr hacky aber es hat funktioniert. –

+0

Genau was ich brauchte. Erwähnenswert ist aber auch die CURLOPT_BUFFERSIZE, die die Chunkgröße definiert. Wenn Ihr Puffer also sehr groß ist, könnte die Chunk-Größe leicht eine ganze Webseite mit Daten enthalten (ich denke!) –

17

Holen Sie sich die ersten 100 Bytes eines Dokuments:

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

aus dem Handbuch

stellen Sie sicher, Sie haben eine moderne curl

+3

Sie sind richtig, aber ich fand, dass es nicht immer zuverlässig ist und hängt auf dem Server und nicht selbst einrollen. In den missverstandenen Fällen würde curl einfach weiter herunterladen. –

+0

Ich kann nicht herunterladen, wenn ich einen anderen Bereich verwende, z. B. 100-200. Ich bekomme "curl error (18)". Kann das gelöst werden? – akashrajkn

0

dies Ihre Lösung sein könnte (Download ersten 500KB in output.txt)

curl -r 0-511999 http://www.yourwebsite.com > output.txt 
  • während 511999 ist 500^1024-1
0

Danke für die nette Lösung Volkerk. Allerdings musste ich diesen Code als Funktion verwenden, also hier ist, was ich herausgefunden habe. Ich hoffe, es ist nützlich für andere. Der Hauptunterschied ist ($ limit, & $ datadump), so dass ein Limit übergeben werden kann und die By-Referenzvariable $ datadump verwendet werden kann, um sie als Ergebnis zurückgeben zu können. Ich habe auch CURLOPT_USERAGENT hinzugefügt, da einige Websites keinen Zugriff ohne einen User-Agent-Header erlauben.

prüfen 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; 
} 

Nutzung:
$ page = curl_get_contents_partial ('http://some.webpage.com', 1000); // lese die ersten 1000 Bytes
echo $ page // oder mache was auch immer mit dem Ergebnis.

Verwandte Themen