Je développe une application qui est, pour le dire simplement, un moteur de recherche de niche. Dans l'application, j'ai inclus une fonction crawl() qui explore un site web puis utilise la fonction collectData() pour stocker les données correctes du site dans la table "products" comme décrit dans la fonction. Les pages visitées sont stockées dans une base de donnéesFuite de mémoire CakePHP Web Crawler
Le crawler fonctionne plutôt bien, comme décrit à l'exception de deux choses: Timeout et Memory. J'ai réussi à corriger l'erreur de délai mais la mémoire reste. Je sais que l'augmentation de memory_limit ne résout pas le problème.
La fonction est exécutée en visitant "EXAMPLE.COM/products/crawl".
Une fuite de mémoire est-elle inévitable avec un robot d'indexation PHP? OU Y at-il quelque chose que je fais mal/ne pas faire.
Merci d'avance. (CODE CI-DESSOUS)
function crawl() {
$this->_crawl('http://www.example.com/','http://www.example.com');
}
/***
*
* This function finds all link in $start and collects
* data from them as well as recursively crawling them
*
* @ param $start, the webpage where the crawler starts
*
* @ param $domain, the domain in which to stay
*
***/
function _crawl($start, $domain) {
$dom = new DOMDocument();
@$dom->loadHTMLFile($start);
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate("/html/body//a");//get all <a> elements
for ($i = 0; $i < $hrefs->length; $i++) {
$href = $hrefs->item($i);
$url = $href->getAttribute('href'); // get href value
if(!(strpos($url, 'http') !== false)) { //check for relative links
$url = $domain . '/' . $url;
}
if($this->Page->find('count', array('conditions' => array('Page.url' => $url))) < 1 && (strpos($url, $domain) !== false)) { // if this link has not already been crawled (exists in database)
$this->Page->create();
$this->Page->set('url',$url);
$this->Page->set('indexed',date('Y-m-d H:i:s'));
$this->Page->save(); // add this url to database
$this->_collectData($url); //collect this links data
$this->_crawl($url, $domain); //crawl this link
}
}
}
Merci pour vos commentaires. Des conseils sur la mise en œuvre de cela? Le concept est relativement simple, mais je ne suis pas sûr de créer une instance distincte. Devrais-je, par exemple, appeler EXAMPLE.COM/products/crawl depuis le script pour exécuter une instance distincte? – KTastrophy
Non, vous préférez travailler avec des tâches cron ou un démon. Il y a beaucoup de discussions ici sur SO pour vous aider à démarrer: http://stackoverflow.com/search?q=php+queue+worker – deceze