2012-04-05 2 views
4

Ich bin simular einige Funktion wie http://pinterest.comadd a pinphp erhalten Sie alle Bilder von URL, die Breite und Höhe> = 200 mehr schneller

Wie alle Bilder von URL zu erhalten, die Höhe und> = 200 mehr schneller Breite? pinterest.com wird den gesamten Prozess fast 10 Sekunden beenden, aber ich brauche 48,64 Sekunden.

require dirname(__FILE__) . '/simple_html_dom.php'; 
$url = 'http://www.huffingtonpost.com/'; 
$html = file_get_html($url); 
if($html->find('img')){ 
    foreach($html->find('img') as $element) { 
     $size = @getimagesize($element->src); 
     if($size[0]>=200&&$size[1]>=200){ 
      echo $element; 
     } 
    } 
}// cost 48.64 seconds 
+0

Wir waren gerade ein Skript, das in 7sec läuft - Still – Baba

Antwort

10

Ich denke, was Sie tun müssen, ist curl Anfragen in parallel mit curl_multi_init Bitte finden Sie unter http://php.net/manual/en/function.curl-multi-init.php für weitere Informationen. Auf diese Weise wird es viel schneller geladen und entgeht allen Bandbreitenproblemen, die sich auch auf die Geschwindigkeit auswirken können.

Speichern Sie das Bild in ein lokales temporäres Verzeichnis nicht getimagesize() auf dem lokalen laufen direkt die als viel schneller ist es läuft über http://

Ich hoffe, das

Edit 1

Hinweis hilft * **

A. Nicht alle Bilder beginnen mit http

B. Nicht alle Bilder sind gültig

C. temp Ordner erstellen, in dem die Bilder

gespeichert werden muss

of Concept Beweisen

require 'simple_html_dom.php'; 
$url = 'http://www.huffingtonpost.com'; 
$html = file_get_html ($url); 
$nodes = array(); 
$start = microtime(); 
$res = array(); 

if ($html->find ('img')) { 
    foreach ($html->find ('img') as $element) { 
     if (startsWith ($element->src, "/")) { 
      $element->src = $url . $element->src; 
     } 
     if (! startsWith ($element->src, "http")) { 
      $element->src = $url . "/" . $element->src; 
     } 
     $nodes [] = $element->src; 
    } 
} 

echo "<pre>"; 
print_r (imageDownload ($nodes, 200, 200)); 
echo "<h1>", microtime() - $start, "</h1>"; 

function imageDownload($nodes, $maxHeight = 0, $maxWidth = 0) { 

    $mh = curl_multi_init(); 
    $curl_array = array(); 
    foreach ($nodes as $i => $url) { 
     $curl_array [$i] = curl_init ($url); 
     curl_setopt ($curl_array [$i], CURLOPT_RETURNTRANSFER, true); 
     curl_setopt ($curl_array [$i], CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)'); 
     curl_setopt ($curl_array [$i], CURLOPT_CONNECTTIMEOUT, 5); 
     curl_setopt ($curl_array [$i], CURLOPT_TIMEOUT, 15); 
     curl_multi_add_handle ($mh, $curl_array [$i]); 
    } 
    $running = NULL; 
    do { 
     usleep (10000); 
     curl_multi_exec ($mh, $running); 
    } while ($running > 0); 

    $res = array(); 
    foreach ($nodes as $i => $url) { 
     $curlErrorCode = curl_errno ($curl_array [$i]); 

     if ($curlErrorCode === 0) { 
      $info = curl_getinfo ($curl_array [$i]); 
      $ext = getExtention ($info ['content_type']); 
      if ($info ['content_type'] !== null) { 
       $temp = "temp/img" . md5 (mt_rand()) . $ext; 
       touch ($temp); 
       $imageContent = curl_multi_getcontent ($curl_array [$i]); 
       file_put_contents ($temp, $imageContent); 
       if ($maxHeight == 0 || $maxWidth == 0) { 
        $res [] = $temp; 
       } else { 
        $size = getimagesize ($temp); 
        if ($size [1] >= $maxHeight && $size [0] >= $maxWidth) { 
         $res [] = $temp; 
        } else { 
         unlink ($temp); 
        } 
       } 
      } 
     } 
     curl_multi_remove_handle ($mh, $curl_array [$i]); 
     curl_close ($curl_array [$i]); 

    } 

    curl_multi_close ($mh); 
    return $res; 
} 

function getExtention($type) { 
    $type = strtolower ($type); 
    switch ($type) { 
     case "image/gif" : 
      return ".gif"; 
      break; 
     case "image/png" : 
      return ".png"; 
      break; 

     case "image/jpeg" : 
      return ".jpg"; 
      break; 

     default : 
      return ".img"; 
      break; 
    } 
} 

function startsWith($str, $prefix) { 
    $temp = substr ($str, 0, strlen ($prefix)); 
    $temp = strtolower ($temp); 
    $prefix = strtolower ($prefix); 
    return ($temp == $prefix); 
} 

Ausgabe

Array 
(
    [0] => temp/img8cdd64d686ee6b925e8706fa35968da4.gif 
    [1] => temp/img5811155f8862cd0c3e2746881df9cd9f.gif 
    [2] => temp/imga597bf04873859a69373804dc2e2c27e.jpg 
    [3] => temp/img0914451e7e5a6f4c883ad7845569029e.jpg 
    [4] => temp/imgb1c8c4fa88d0847c99c6f4aa17a0a457.jpg 
    [5] => temp/img36e5da68a30df7934a26911f65230819.jpg 
    [6] => temp/img068c1aa705296b38f2ec689e5b3172b9.png 
    [7] => temp/imgfbeca2410b9a9fb5c08ef88dacd46895.png 
) 
0.076347 

Dank :)

+0

das ist eine großartige Methode, vielen Dank. einige Probleme: Wie bekomme ich die url des rohen Images, nicht die Ausgabe im lokalen temporären Ordner? –

+1

Das ist einfach zu ersetzen '$ res [] = $ temp;' mit '$ res [] = $ url;' das würde die Tric .. nicht vergessen, auch alles zu "lösen" – Baba

+0

@Baba Bitte ändern Sie diese Bedingung 'if ($ size [0]> = $ maxHeight && $ size [0]> = $ maxWidth)'. Vielleicht möchtest du diese $ size [0] in $ size [1] für $ maxHeight comparison ändern – Rajasekhar

2

getimagesize() wird zuerst die GESAMTE Bilddatei herunterladen und dann die Analyse durchführen. Im Allgemeinen benötigen Sie nur die ersten paar hundert Bytes der Datei, um Typ-/Auflösungsdetails zu erhalten. Außerdem wird für jedes Bild eine separate HTTP-Anfrage verwendet.

Ein richtig optimiertes System würde eine Partial-Get-Anforderung verwenden, um nur den ersten Teil des Abbilds abzurufen, und den Vorteil von http keep-alives nutzen, um den TCP-Verbindungsaufwand gering zu halten.

+0

Dank des Tests kann u geben Sie mir einige Code-Beispiel für Referenz? –

+1

Partial-Gets sind hier definiert: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.Im Grunde genommen ist das nur eine normale Anfrage, aber mit einem 'Range:' - Header, um anzugeben, welche Bytes übertragen werden sollen. Sie können curl verwenden, um persistente HTTP-Anfragen zu machen: http://php.net/curl –

1

Und was ist mit dem Lesen von Breite und Höhe von HTML? Ich weiß, dass einige der Bilder diese Attribute möglicherweise nicht haben, aber vielleicht können Sie Bilder mit diesen Attributen kleiner als 200px einfach überspringen.

Es ist nur eine Idee, aber vielleicht nicht für Sie nutzbar.

1

Reference

Verwenden imagecreatefromstring, imagesx und imagesy, Dies sollte innerhalb von 30 Sekunden ausgeführt werden. (Ein bisschen schneller als getimagesize)

function ranger($url){ 
    $headers = array("Range: bytes=0-32768"); 
    $curl = curl_init($url); 
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
    return curl_exec($curl); 
    curl_close($curl); 
} 
require dirname(__FILE__) . '/simple_html_dom.php'; 
$url = 'http://www.huffingtonpost.com/'; 
$html = file_get_html($url); 
if($html->find('img')){ 
    foreach($html->find('img') as $element) { 
     $raw = ranger($element->src); 
     $im = @imagecreatefromstring($raw); 
     $width = @imagesx($im); 
     $height = @imagesy($im); 
     if($width>=200&&$height>=200){ 
      echo $element; 
     } 
    } 
} 
Verwandte Themen