2010-01-21 10 views
1

간단히 말해 틈새 기반 검색 엔진 인 애플리케이션을 개발 중입니다. 응용 프로그램 내에서 웹 사이트를 크롤링 한 다음 함수에서 설명한대로 collectData() 함수를 사용하여 사이트의 올바른 데이터를 "제품"테이블에 저장하는 함수 crawl()을 포함 시켰습니다. 방문한 페이지는 데이터베이스에 저장됩니다.CakePHP 웹 크롤러 메모리 누수

크롤러는 시간 초과 및 메모리의 두 가지 경우를 제외하고는 설명 된 것처럼 작동합니다. 시간 초과 오류를 해결할 수 있었지만 메모리는 남아 있습니다. 나는 단순히 memory_limit를 늘리는 것이 실제로 문제를 해결하지 않는다는 것을 안다.

"EXAMPLE.COM/products/crawl"을 방문하여 기능을 실행합니다.

PHP 웹 크롤러에서 메모리 누출이 필연적입니까? 또는 내가하고있는 일이 잘못되었거나하지 않은 것입니다.

미리 감사드립니다. (아래 CODE)

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 
      } 
     } 
    } 

답변

1

페이지의 링크가있는 한 당신은 위쪽으로 두 배나 많은 데이터베이스 쿼리의 만드는, 당신의 문제가 어디 그건 말할 것. 배열로 링크를 누적하고 중복을 필터링하고 saveAll()으로 새 레코드를 삽입하는 큰 일괄 쿼리를 수행하십시오.


실제로 다시 보았을 때 모든 링크가 재귀 적으로 크롤링되지만 깊이 제한이나 중단 조건은 없습니다. 즉, 스크립트는 잠재적으로 무한한 따라야 할 링크가있는 한 계속됩니다. 한 번에 한 페이지 씩 처리하고 다른 인스턴스의 추가 링크를 크롤링해야합니다 (예 : 대기열/작업자 패턴 사용).

+0

의견을 보내 주셔서 감사합니다. 이 구현에 대한 도움말? 이 개념은 비교적 솔직하게 진행되지만 별도의 인스턴스를 만들 때 확실하지 않습니다. 예를 들어 별도의 인스턴스를 실행하기 위해 스크립트 내에서 EXAMPLE.COM/products/crawl을 호출해야합니까? – KTastrophy

+0

아니, 당신은 오히려 cron 작업이나 데몬으로 작업 할 것입니다. 시작하기 위해 여기에 많은 스레드가 있습니다. http://stackoverflow.com/search?q=php+queue+worker – deceze