Page 1 sur 2
Fonction récursive : Help
Posté : 06 janv. 2016, 13:47
par CoeurBis
Salut,
Je cherche à faire un genre de mini-crawler et pour cela, voici ma page :
Code : Tout sélectionner
<?php
function in_multi_array($value, $array)
{
foreach ($array as $key => $item)
{
if (!is_array($item))
{
if ($item == $value) return true;
}
else
{
if (in_array($value, $item)) return true;
else if (in_multi_array($value, $item)) return true;
}
}
return false;
}
function racine($site)
{
$site = explode('/', $site);
if( strstr($site[2], 'www.') )
{
$site = explode('www.', $site[2]);
return $site[1];
}
else
{
return $site[2];
}
}
function crawlcurl($url)
{
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
$code_brute = curl_exec($ch);
curl_close($ch);
return $code_brute;
}
function crawl($url, &$urls, $limite)
{
$code_brute = crawlcurl($url);
$doc = new DOMDocument();
$doc->loadHTML($code_brute);
$balise_a = $doc->getElementsByTagName('a');
foreach($balise_a as $balise)
{
$href = $balise->getAttribute('href');
if( !in_multi_array($href, $urls) && strstr($href, racine($url)) && !strstr($href, 'pdf') )
{
if( $limite >= 0 )
{
$urls[] = $href;
$urls[] = crawl($href, $urls, ($limite - 1));
}
else
{
$urls[] = $href;
}
}
$limite = ($limite - 1);
}
return $urls;
}
$liste = crawl('http://www.canardduweb.fr', $liste, 1);
print_r($liste);
?>
Je voudrais qu'avec la limite de 1, le script puisse crawler a une profondeur de 1, donc récupérer toutes les URLs de l'url active.
Avec une limite de 2, le script devrait récupérer toutes les URLs de la page active, puis vérifier toutes les URLs de ces urls et une fois de plus... Etc.
Le problème est que je récupère uniquement les liens du premier de la liste uniquement...
Bref mon code bloque quelque part et après plusieurs jours dessus, je ne trouve pas encore comment faire fonctionner ce code...
Merci de votre aide.
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 14:40
par Patriboom
Tu as un appel en boucle
Code : Tout sélectionner
function crawl($url, &$urls, $limite)
{
...
foreach($balise_a as $balise)
{
$href = $balise->getAttribute('href');
if( !in_multi_array($href, $urls) && strstr($href, racine($url)) && !strstr($href, 'pdf') )
{
if( $limite >= 0 )
{
$urls[] = $href;
$urls[] = crawl($href, $urls, ($limite - 1)); // ICI la fonction crawl appelle la fonction crawl
...
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 15:40
par CoeurBis
En fait, c'est le principe de la fonction récursive mais je l'ai mal appliquée je pense, j'ai besoin d'aide pour savoir comment modifier ce code.
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 17:42
par Spols
Je n'arrive pas à suivre ton code, tu as plus d'une fonction récursive, et je pense que la profondeur dans ton tableau $urls est inutile
Mais pour avoir déjà fait un robot de parcours de site,
J'ai suivi une tout autre voix.
à partir d'une adresse, je récupère tous les href, si il sont dans mon tableau, j'ajoute une entrée "parent" avec l'url courante sinon j'ajoute dans mon tableau avec l'entrée "parent". Je parcours mon tableau avec une boucle while et une variable $i qui s'incrémente à chaque boucle. Mais comme j'augmente mon tableau d'url au fur et à mesure, je continue de le parcourir (ma condition while est empty($tableau[$i]))
Et si tu veux y adjoindre un contrôle de profondeur, il suffit de l'ajouter dans ton tableau (avec un fonction min(), car tu dois savoir sa profondeur minimum dans ta hiérarchie) et une condition d'exclusion en début de while
La structure de mon tableau d'url
Code : Tout sélectionner
$array = array(
array(
'url' => 'MonUrl',
'parent' => 'UrlParent'
'depth' => min('profondeur')
)
)
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 17:57
par ynx
Salut,
Le troisième paramètre $limite de la fonction récursive crawl(), qui correspond à la profondeur du crawl, doit donc être décrémenté à chaque appel de cette fonction (ce que tu fais bien avec la ligne $urls[] = crawl($href, $urls, ($limite - 1));).
Par contre tu décrémentes également cette variable à chaque fois qu'un lien est récupéré (à la fin de la boucle foreach($balise_a), ce qui ne me semble pas correct puisque en parcourant tous les liens d'une page tu es toujours au même niveau de profondeur.
Sauf erreur (pas testé donc c'est pas impossible), il suffit que tu supprimes cette décrémentation dans la boucle pour faire fonctionner correctement ta fonction récursive.
Bonne journée,
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 17:57
par CoeurBis
Salut,
merci pour ces informations et ces idées. Mais j'ai un besoin bien précis à ce sujet, c'est la première partie seulement et j'ai du coup besoin d'une fonction avec laquelle je peux définir la profondeur que je souhaite crawler à partir de l'URL que je donne.
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 18:02
par CoeurBis
Salut,
Le troisième paramètre $limite de la fonction récursive crawl(), qui correspond à la profondeur du crawl, doit donc être décrémenté à chaque appel de cette fonction (ce que tu fais bien avec la ligne $urls[] = crawl($href, $urls, ($limite - 1));).
Par contre tu décrémentes également cette variable à chaque fois qu'un lien est récupéré (à la fin de la boucle foreach($balise_a), ce qui ne me semble pas correct puisque en parcourant tous les liens d'une page tu es toujours au même niveau de profondeur.
Sauf erreur (pas testé donc c'est pas impossible), il suffit que tu supprimes cette décrémentation dans la boucle pour faire fonctionner correctement ta fonction récursive.
Bonne journée,
Voici ce que ça donne si je supprime la décrémentation à la fin de la boucle, sur un petit site :
Code : Tout sélectionner
Array
(
[0] => http://www.jscourses.com
[1] => http://www.jscourses.com/
[2] => http://www.jscourses.com/services
[3] => http://www.jscourses.com/tarifs
[4] => http://www.jscourses.com/reserver
[5] => http://www.jscourses.com/gare-de-lyon
[6] => http://www.jscourses.com/gare-de-lyon/taxi-moto-gare-de-lyon
[7] => Array
(
[0] => http://www.jscourses.com
[1] => http://www.jscourses.com/
[2] => http://www.jscourses.com/services
[3] => http://www.jscourses.com/tarifs
[4] => http://www.jscourses.com/reserver
[5] => http://www.jscourses.com/gare-de-lyon
[6] => http://www.jscourses.com/gare-de-lyon/taxi-moto-gare-de-lyon
)
[8] => Array
(
[0] => http://www.jscourses.com
[1] => http://www.jscourses.com/
[2] => http://www.jscourses.com/services
[3] => http://www.jscourses.com/tarifs
[4] => http://www.jscourses.com/reserver
[5] => http://www.jscourses.com/gare-de-lyon
[6] => http://www.jscourses.com/gare-de-lyon/taxi-moto-gare-de-lyon
[7] => Array
(
[0] => http://www.jscourses.com
[1] => http://www.jscourses.com/
[2] => http://www.jscourses.com/services
[3] => http://www.jscourses.com/tarifs
[4] => http://www.jscourses.com/reserver
[5] => http://www.jscourses.com/gare-de-lyon
[6] => http://www.jscourses.com/gare-de-lyon/taxi-moto-gare-de-lyon
)
)
)
Je pense que c'est pas encore ça... Mais on s'en rapproche peut-être

Re: Fonction récursive : Help
Posté : 06 janv. 2016, 21:16
par Patriboom
Bonjour à tous,
je vois que CoeurBis progresse bien dans son projet.
Une petite présentation du code nous permettrait de savoir où c'en est. Je vois qu'il y eut beaucoup de progrès depuis.
Le résultat affiché ci-haut n'est-il pas ce que vous souhaitez?
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 21:28
par CoeurBis
Bonjour à tous,
je vois que CoeurBis progresse bien dans son projet.
Une petite présentation du code nous permettrait de savoir où c'en est. Je vois qu'il y eut beaucoup de progrès depuis.
Le résultat affiché ci-haut n'est-il pas ce que vous souhaitez?
Salut Patriboom,
J'ai mis tout au début, le code complet de la page, qui est actuellement en phase de tests. Une fois réussi, je pourrais l'adapter plus précisément. Ce code est donc indépendant actuellement.
Le résultat que je veux c'est :
Code : Tout sélectionner
Array
(
[0] => page1.html
[1] => Array
(
[0] => page1a.html
[1] => page1b.html
[2] => page1c.html
[3] => page1d.html
[4] => page1e.html
}
[2] => page2.html
[3] => Array
(
[0] => page2a.html
[1] => page2b.html
[2] => page2c.html
[3] => page2d.html
[4] => page2e.html
}
[4] => page3.html
[5] => Array
(
[0] => page3a.html
[1] => page3b.html
[2] => page3c.html
[3] => page3d.html
[4] => page3e.html
}
)
Et pour une profondeur de 3 par exemple ce serait :
Code : Tout sélectionner
Array
(
[0] => page1.html
[1] => Array
(
[0] => page1a.html
[1] => Array
(
[0] => page1aa.html
[1] => page1ab.html
[2] => page1ac.html
[3] => page1ad.html
[4] => page1ae.html
}
[2] => page1b.html
[3] => Array
(
[0] => page1ba.html
[1] => page1bb.html
[2] => page1bc.html
[3] => page1bd.html
[4] => page1be.html
}
[4] => page1c.html
[5] => Array
(
...
Enfin, agencé comme ça ou même un peu différemment, mais ce sont bien ces données qu'il me faut.
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 21:36
par CoeurBis
D'ailleurs, j'ai l'impression que ma fonction in_multi_array ne fonctionne pas...
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 22:16
par Patriboom
Si ta fonction in_multi_array n'est pas appelée, il faut que tu te questionne sur la façon de l'appeler.
Quant moi, j'ai des doutes relativement à
dans
Code : Tout sélectionner
if( !in_multi_array($href, $urls) && strstr($href, racine($url)) && !strstr($href, 'pdf') )
Est-ce qu'une URL complète peut être dans sa racine?
La logique ne nous demanderait-elle pas l'inverse (que la racine se trouve dans l'URL complète ) ?
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 22:19
par CoeurBis
En fait, je fais des tests sur des sites qui ont des URLs absolues, donc avec la racine complète.
Si ça marche, ensuite je pense prendre ceux sans la racine (relatifs) et ajouter le préfix afin de les crawler... Donc le problème ne vient pas de là à mon avis.
Re: Fonction récursive : Help
Posté : 06 janv. 2016, 23:13
par Patriboom
N'empêche, ton test ne devrait-il pas être plutôt ainsi :
Re: Fonction récursive : Help
Posté : 07 janv. 2016, 00:28
par CoeurBis
Non, car je recherche bien si la racine du site ext présent dans l'URL en question, par exemple :
Re: Fonction récursive : Help
Posté : 07 janv. 2016, 01:14
par Patriboom
bref, as-tu vérifié si ta routine passe par ta fonction in_multi_array ? Insères-y des echo, des marqueurs qui te permettent de vérifier si la sous-routine est appelée.
Si elle n'est pas appelée, insère des echo affichant les variables qui sont vérifiées par ton if (!in_multi_array)
comme ceci:
Code : Tout sélectionner
$href = $balise->getAttribute('href');
echo 'Voici href = '.$href.'<br />';
echo 'Voici urls = '.$urls).'<br />';
echo 'Voici racine(url) = '.racine($url)).'<br />';
echo 'Voici est-ce un pdf = '. ((strstr($href, 'pdf') ) ? 'oui' : 'non').'<br />';
if( !in_multi_array($href, $urls) && strstr($href, racine($url)) && !strstr($href, 'pdf') )