Recuperer header d'une image rapidement

Recuperer header d'une image rapidement - PHP - Programmation

Marsh Posté le 28-01-2010 à 20:16:05    

J'utilise un petit script qui vient parser le code source d'une page pour récupérer tous les liens des images d'une url.
Celui-ci retourne tous les liens des images dont le poids est supérieur à une certaine valeur.
Seulement, suivant la page parsée cela peut prendre jusqu'à une minute...
J'aimerais savoir s'il y a une meilleure façon de faire qui serait plus rapide.

 

Voici le code:

Code :
  1. $adresse_page = $_POST["url"];
  2.  
  3. $code_source = file_get_contents($adresse_page);
  4.  
  5. $nbr_images = substr_count($code_source, '.jpg');
  6.  
  7. if ($nbr_images != '0'){
  8.        $i = 0;
  9.     $pos_image   = strpos($code_source, 'http');   //position estimée d'une adresse d'image
  10.     $fin_image     = strpos($code_source, 'jpg', $pos_image) + 3;           //position de la fin d'une adresse d'image
  11.     $longueur = $fin_image-$pos_image;    
  12.     
  13.     while ($i < $nbr_images){
  14.         if ($longueur < '150'){                 //estime longueur d'un lien image à moins de 150 caracteres
  15.             $liste_images[$i] = substr($code_source, $pos_image, $longueur);   //recupere l'adresse de l'image
  16.             $header = (get_headers($liste_images[$i],1)); //recupere header de l'image
  17.             $test = substr($header[0], 9,3);  
  18.             $poids = $header['Content-Length'];
  19.             if ($test == '200' && $poids >=5000) {               //test si lien valide et poids > 5ko
  20.                 echo $liste_images[$i].";";                       //retourne cette adresse
  21.             }
  22.             $pos_image   = strpos($code_source, 'http',$fin_image);
  23.             $fin_image     = strpos($code_source, 'jpg', $pos_image) + 3;
  24.             $longueur = $fin_image-$pos_image;    
  25.             $i++;
  26.         }
  27.         else {
  28.             $pos_image   = strpos($code_source, 'http',$pos_image + 4);
  29.             if ($pos_image > $fin_image){
  30.                 $fin_image     = strpos($code_source, 'jpg', $pos_image) + 3;
  31.                 $longueur = $fin_image-$pos_image;
  32.                 $i++;
  33.             }
  34.             else {    
  35.                 $longueur = $fin_image-$pos_image;
  36.             }
  37.         }
  38.     }
  39. }


Message édité par garath_ le 29-01-2010 à 13:27:55
Reply

Marsh Posté le 28-01-2010 à 20:16:05   

Reply

Marsh Posté le 29-01-2010 à 11:56:29    

ouai c'est pas terrible de joué avec les fonction str pour parser du contenu,
 
pour parser une page (x)html, c'est DomDocument,  tu peux faire des requete xpath (ex : chercher toute les balises image)
 

Code :
  1. <?php
  2. libxml_use_internal_errors(true);
  3.  
  4. define('MIN_SIZE', 1000);
  5. $url = 'http://images.google.fr/images?q=google';
  6.  
  7. $parse       = parse_url($url);
  8. $baseurl     = $parse['scheme'] . '://' . $parse['host'] . '/';
  9.  
  10. $dom = new DomDocument();
  11. $dom->loadHTMLFile($url);
  12.  
  13. $xpath  = new DOMXPath($dom);
  14. $items = $xpath->query('//img/@src');
  15.  
  16. $images = array();    
  17. $temp   = array();
  18.  
  19. foreach($items as $item)
  20. {
  21.    $temp[] = $item->value;
  22. }
  23.  
  24. $temp = array_unique($temp);
  25.  
  26. foreach($temp as $image)
  27. {
  28.    if(!preg_match("/^{$parse['scheme']}/" , $image))
  29.    {
  30.        $image = $baseurl . $image;
  31.    }
  32.    
  33.    $header = get_headers($image, 1);
  34.    
  35.    if(isset($header['Content-Length']))
  36.    {
  37.        $content     = $header['Content-Length'];
  38.        $size        = '';
  39.        
  40.        if(is_array($content))
  41.        {
  42.            $size = array_pop($content);
  43.        }
  44.        else
  45.        {
  46.            $size = $content;
  47.        }
  48.        
  49.        if($size > MIN_SIZE)
  50.        {
  51.            $images[] = array('file' => $image, 'size' => $size);
  52.        }        
  53.    }
  54. }    
  55.  
  56. echo '<pre>' . print_r($images, true) . '</pre>';


Message édité par stealth35 le 29-01-2010 à 11:59:29
Reply

Marsh Posté le 29-01-2010 à 13:50:50    

Wah merci de la réponse j'en espérais pas tant.
C'est vrai que j'ai pas trop creusé du coté des fonctions Dom.
 
 :love: En plus ta fonction enlève les doublons (je suis noob en php donc quand je découvre des fonctions qui font simplement des trucs qui me semblent galère à faire ça m'émerveille)
 
Si tu as juste une petite explication sur ça :

Code :
  1. if(!preg_match("/^{$parse['scheme']}/" , $image))
  2.   {
  3.       $image = $baseurl . $image;
  4.   }


 
que je ne comprend pas très bien.
 
En tout cas merci de ton aide  :hello:

Reply

Marsh Posté le 29-01-2010 à 14:09:20    

re, content que tu ai compris le reste du code, c'est tres bien ;)
 
pour la fonction c'est un petit expression relationnelle, pour verifié si la line commence par : http,
ou pourrais juste faire
 
preg_match("/^http/" , $image)
 
ducoup si y'a pas, il rajoute la base de l'adresse
 

Reply

Marsh Posté le 29-01-2010 à 15:43:56    

Ok compris.
 
Par contre ta fonction retourne (affiche), le contenu du tableau $images avec leur taille entre 2 balise <pre>, c'est bien ça?
 
J'ai pas vraiment besoin de la taille de l'image, c'est juste pour éviter de récupérer les icônes d'une page.
 
Je pense juste faire ça:
 
A la place de:

Code :
  1. if($size > MIN_SIZE)
  2.       {
  3.           $images[] = array('file' => $image, 'size' => $size);
  4.       }


 
Mettre:

Code :
  1. if($size > MIN_SIZE)
  2.       {
  3.            echo $image . ';' ;
  4.       }

 
 
Juste histoire que ça s'adapte à mon interprétation de l'autre coté.

Reply

Marsh Posté le 29-01-2010 à 15:47:23    

non faudra mettre
 

Code :
  1. $images[] = $image;

Reply

Marsh Posté le 01-02-2010 à 22:11:08    

Merci ça marche nickel!
Une vingtaine de seconde pour récupérer les images d'une page.
Mon site est en local pour l'instant, peut être faudra t'il moins longtemps quand il sera en ligne.

Reply

Marsh Posté le 01-02-2010 à 22:42:36    

hello,  
ouai c'est pas tip top, mais c'est d'aller cherche les header qui prend du temps.
APres a quoi sert exactement ton script, y'a peux etre une autre solution  
;)

Reply

Marsh Posté le 01-02-2010 à 23:14:04    

En fait, l'utilisateur fournit l'adresse d'une page.
Le script récupère alors toutes les adresses des images contenus sur cette page et affiche les images dans une visionneuse (en javascript d'ailleurs j'ai d'autres soucis avec cette visionneuse, voir mon autre topic)
L'utilisateur choisit celle qui l'intéresse et à ce moment là je rehost l'image choisie.
 
Je pense pas qu'il y ait un meilleur moyen...

Reply

Marsh Posté le 02-02-2010 à 09:58:16    

faudrais essayer que l'utilisateur affiche la page (en la rendant invisible en espece d'iframe), et récupérer les image a partir du cache du client,  a voir...

Reply

Marsh Posté le 02-02-2010 à 09:58:16   

Reply

Marsh Posté le 02-02-2010 à 10:28:32    

A voir pour une future amélioration...
Pour l'instant ça va bien comme ça, j'ai un gif qui indique le chargement des images pour patienter.
Facebook procède de la même façon je pense quand on insère un lien dans un message, j'ai remarqué ça ce week end...

Reply

Marsh Posté le 02-02-2010 à 14:09:09    

tu peux jouer avec le buffer sinon,
ex :  les liens s'affiche petit a petit
 
je te post un code

Reply

Marsh Posté le 02-02-2010 à 14:13:53    

Code :
  1. if($size > MIN_SIZE)
  2. {
  3.    $images[] = $image;
  4.  
  5.    echo 'Found : '. $image . '<br />' . PHP_EOL;
  6.            
  7.    ob_flush();
  8.    flush();
  9. }


Message édité par stealth35 le 02-02-2010 à 14:14:18
Reply

Marsh Posté le 02-02-2010 à 22:52:40    

Je viens de tester de rajouter les fonctions de buffer, ça m'a retourné ça:

 

<b>Notice</b>:  Use of undefined constant flush...

 

J'ai peut être mal utilisé ces fonctions, car j'ai adapté un peu la fin de ton script...


Message édité par garath_ le 02-02-2010 à 22:52:51
Reply

Marsh Posté le 02-02-2010 à 22:57:09    

remet ton code, ca fait comme si t'avais pas mis les parenthèses

Reply

Marsh Posté le 02-02-2010 à 23:00:29    

[:the geddons] quel boulet...
EDIT: ceci dit ça ne change pas la durée de récupération de la liste d'image.
J'appel ce script par de l'ajax ceci explique peut être cela...


Message édité par garath_ le 02-02-2010 à 23:03:18
Reply

Marsh Posté le 02-02-2010 à 23:12:41    

ah bah ouai mince, t'as APC d'installer ?  t'utilisequoi comme lib pour ton appel ajax ?


Message édité par stealth35 le 02-02-2010 à 23:13:17
Reply

Marsh Posté le 02-02-2010 à 23:15:05    

pas de lib (enfin je crois) je fais tout "à la main"....

Reply

Marsh Posté le 02-02-2010 à 23:31:46    

et pour APC

Reply

Marsh Posté le 03-02-2010 à 15:12:13    

Non plus (si j'ai bien compris...)
Pour l'instant je test le site en local sur ma machine et j'ai activé le minimum extension.

Reply

Marsh Posté le 05-05-2010 à 11:29:32    

J'up le sujet car j'ai un petit souci:
 

Code :
  1. $url = $_POST["url"];
  2.  
  3.  
  4. //libxml_use_internal_errors(true);
  5.  
  6. define('MIN_SIZE', 3000);
  7.  
  8.  
  9. $parse       = parse_url($url);
  10. $baseurl     = $parse['scheme'] . '://' . $parse['host'] . dirname($parse['path']) . '/';
  11. $dom = new DomDocument();
  12. @$dom->loadHTMLFile($url);
  13.  
  14. $xpath  = new DOMXPath($dom);
  15. $items = $xpath->query('//img/@src');
  16.  
  17. $images = array();    
  18. $temp   = array();
  19.  
  20. foreach($items as $item)
  21. {
  22.     $temp[] = $item->value;
  23. }
  24.  
  25. $temp = array_unique($temp);
  26.  
  27. foreach($temp as $image)
  28. {
  29.   if(!preg_match("/^{$parse['scheme']}/" , $image))
  30.   {
  31.       $image = $baseurl . $image;
  32.   }
  33.  
  34.   $header = get_headers($image, 1);
  35.   if(isset($header['Content-Length']))
  36.   {
  37.       $content     = $header['Content-Length'];
  38.       $size        = '';
  39.       if(is_array($content))
  40.       {
  41.           $size = array_pop($content);
  42.       }
  43.       else
  44.       {
  45.           $size = $content;
  46.       }
  47.       if($size > MIN_SIZE)
  48.       {
  49.           //$images[] = array('file' => $image, 'size' => $size);
  50.             echo $image . ';' ;
  51.         }            
  52.   }
  53. }


 
Ce code fonctionne bien quand les images sont stockées dans un sous dossier du repertoire de la page parsée.
Par contre quand les images sont stockées à un tout autre endroit, ça foire evidemment...
 
Exemple:
 
Je lui passe l'url http://online.carrefour.fr/Produit [...] roduit.php
Les images sur cette pages sont stockées ici: http://online.carrefour.fr/images/ [...] roduit.gif
alors que mon script va me retourner l'adresse de l'image http://online.carrefour.fr/Produit [...] roduit.gif
 
(Oui j'ai bien vu le double slash qui vient de mon script mais si je ne l'inclue pas ça ne fonctionne pas sur d'autres sites...)
 
Y a t'il moyen de modifier ça pour que ça s'adapte à toutes les arborescences de site?


---------------
HFR Links Preview | HFR Giphy
Reply

Marsh Posté le 07-05-2010 à 15:54:09    

Code :
  1. dirname($parse['path'])


ca veut rien dire ça :D

 

l'argument que prend dirname() est un chemin absolu dans un système de fichier, pas un bout d'URL.

Message cité 1 fois
Message édité par theredled le 07-05-2010 à 16:02:01

---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 07-05-2010 à 16:00:32    

theredled a écrit :

Code :
  1. dirname($parse['path'])


ca veut rien dire ça :D
 
l'argument que prend dirname() est un chemin absolu dans un système de fichier, pas un bout d'URL.


Nein, ça dirname sur ce que tu veux. Ça regarde même pas le FS, mais bêtement les différentes directory separators

Reply

Marsh Posté le 07-05-2010 à 16:35:26    

Ouep c'est d'ailleurs ça qui me fait tout déconner.
Parce que ça prend les directory separators de l'url de la page passée en argument mais pas de l'image ciblée. (bien souvent c'est les mêmes, mais parfois, parfois... non)


Message édité par garath_ le 07-05-2010 à 16:36:09

---------------
HFR Links Preview | HFR Giphy
Reply

Marsh Posté le 07-05-2010 à 17:22:38    

FlorentG a écrit :


Nein, ça dirname sur ce que tu veux. Ça regarde même pas le FS, mais bêtement les différentes directory separators


bon ok [:dawao]


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 18-05-2010 à 18:11:10    

Up  [:meganne]


---------------
HFR Links Preview | HFR Giphy
Reply

Marsh Posté le 02-06-2010 à 08:48:36    

Personne pour expliquer comment récupérer le chemin complet des images présentes sur une page?
 [:agkklr]


---------------
HFR Links Preview | HFR Giphy
Reply

Marsh Posté le 02-06-2010 à 09:57:36    

garath_ a écrit :

Personne pour expliquer comment récupérer le chemin complet des images présentes sur une page?
 [:agkklr]


Si tu n'as pas de <base> dans ton head :
 
Si l'URL de l'image est relative à la page (dir/img.jpg) :
dirname(l'URL de la page).'/'.$url_image;
 
Si l'URL de l'image est relative au NDD (/dir/img.jpg) :
'http://'.parse_url($url_page, PHP_URL_HOST).$url_image;
 
Si l'URL de l'image est absolue (http://machin.com/dir/img.jpg) :
Tu la garde telle quelle
 
C'est ça que tu veux faire ?


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 02-06-2010 à 12:21:23    

En partie oui.
Il arrive parfois que sur une page http://www.url.fr/bidule/truc , les images soient dans http://www.url.fr/image où ailleurs...
Enfin dans un dossier non relatif à l'adresse de la page mais au NDD comme tu as dit.
Seulement comme je veux pouvoir récupérer des images sur n'importe quel site, indifféremment de leur localisation des images, je ne sais pas faire un truc universel...


---------------
HFR Links Preview | HFR Giphy
Reply

Marsh Posté le 02-06-2010 à 12:27:51    

garath_ a écrit :

En partie oui.
Il arrive parfois que sur une page http://www.url.fr/bidule/truc , les images soient dans http://www.url.fr/image où ailleurs...
Enfin dans un dossier non relatif à l'adresse de la page mais au NDD comme tu as dit.
Seulement comme je veux pouvoir récupérer des images sur n'importe quel site, indifféremment de leur localisation des images, je ne sais pas faire un truc universel...


Bah si tu fais ce que j'ai dit, tu parses déja 95% des pages web, non ?


Message édité par theredled le 02-06-2010 à 12:28:05

---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 02-06-2010 à 13:33:47    

Après relecture de ce que tu proposes il semble bien oui  :o .
 
Si je comprend bien il faut que je rajoute une condition dans cette partie du code (qui construit une adresse d'image relative à l'adresse de la page ou sinon garde l'adresse absolue):

Code :
  1. if(!preg_match("/^{$parse['scheme']}/" , $image))
  2.   {
  3.       $image = $baseurl . $image;
  4.   }


 
Cette condition testerai si l'url de l'image est relative au NDD. C'est ça?


---------------
HFR Links Preview | HFR Giphy
Reply

Marsh Posté le 02-06-2010 à 14:12:14    

Voilà, tu regardes juste si elle commence par un slash quoi.


---------------
Contes de fées en yaourt --- --- zed, souviens-toi de ma dernière lettre. --- Rate ta musique
Reply

Marsh Posté le 02-06-2010 à 15:56:36    

OK, je vais essayer ça.
Merci.


---------------
HFR Links Preview | HFR Giphy
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed