Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 递归站点爬虫_Php_Recursion - Fatal编程技术网

Php 递归站点爬虫

Php 递归站点爬虫,php,recursion,Php,Recursion,有几个现有的网站,我需要将所有的URL和内容输入Elasticsearch,因此通过一些示例,我构建了一种方法来获取网站上的所有内部链接,并将它们放入一个数组中。问题是我看到的每个例子都不是完全递归的,有一个深度设置。在过去的6个小时里,我一直在(认真地)尝试各种不同的方法使它完全递归。我现在是这样做的,但我认为我正在无限循环和崩溃,因为在运行一分钟后,我没有收到任何错误,只有一个“没有收到数据”页面。我愿意接受任何关于更好方法的建议 <?php set_time_limi

有几个现有的网站,我需要将所有的URL和内容输入Elasticsearch,因此通过一些示例,我构建了一种方法来获取网站上的所有内部链接,并将它们放入一个数组中。问题是我看到的每个例子都不是完全递归的,有一个深度设置。在过去的6个小时里,我一直在(认真地)尝试各种不同的方法使它完全递归。我现在是这样做的,但我认为我正在无限循环和崩溃,因为在运行一分钟后,我没有收到任何错误,只有一个“没有收到数据”页面。我愿意接受任何关于更好方法的建议

    <?php
    set_time_limit (1209600);
    ini_set('memory_limit', '-1');

    $seen = array();
    $urls = crawl_page("http://example.com", $seen);

    foreach($urls as $url){
        echo $url.'<br />';
    }

    function crawl_page($url, $seen){

        //CURL TO GRAB PAGE
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        $result = curl_exec ($ch);
        curl_close ($ch);


        //URL NO HTTP/S OR WWW
        $urlStripped = str_replace('www', '', $url);
        $urlStripped = str_replace('http://', '', $urlStripped);
        $urlStripped = str_replace('https://', '', $urlStripped);

        //ADD THIS URL TO THE ARRAY
        if(!in_array($url, $seen)){
            $seen[] = $url;
        }


        //GET ALL LINKS IN PAGE
        $stripped_file = strip_tags($result, "<a>");
        preg_match_all("/<a[\s]+[^>]*?href[\s]?=[\s\"\']+"."(.*?)[\"\']+.*?>"."([^<]+|.*?)?<\/a>/", $stripped_file, $matches, PREG_SET_ORDER ); 
        foreach($matches as $match){
            $href = $match[1];
            //MAKE SURE LINK ISNT DUPLICATE AND MAKE SURE THE LINK IS INTERNAL
            if(!in_array($href, $seen) && is_in_string($urlStripped, $href)){
                $seen[] = $href;
            }
        }

        //HERE'S WHERE THE PROBLEM LIES, ATTEMPTING TO MAKE THIS RECURSIVE. 
        //I'VE DONE THIS MANY DIFFERENT WAYS WITH NO LUCK.
        //I DON'T REALLY HAVE A REASON FOR IT'S CURRENT STATE.
        //I ENDED UP TAKING SHOTS IN THE DARK AND THATS WHAT LED ME TO ASK ON STACKOVERFLOW
        $seenTemp1 = $seen;
        foreach($seenTemp1 as $aUrl){
            $seenTemp2 = crawl_page($aUrl, $seenTemp1);
            $seen = array_merge($seen, $seenTemp2);
        }

        //RETRUN ARRAY
        return $seen;
    }

    function is_in_string($needle, $string){
        $before = strlen($string);
        $after = strlen(str_replace($needle, '', $string));

        if($before != $after){
            return true;
        }
        else{
            return false;
        }
    }

?>


Yeah的可能重复,但我如何在PHP中做到这一点,以便在最后我可以循环通过最终数组并将这些URL插入到附加到弹性搜索的数据库中。你总是希望有一个深度设置,否则你可能会被困在蜂蜜陷阱网站上(它们有无限的深度)。我在这里没有看到任何
sleep()
——如果您不想在其他人的web服务器上造成拒绝服务,您应该添加这一点。至于这个问题,调试出了什么结果?深度(比如说)5应该可以满足大多数网站的需求,在重复出现的时候就打折。在
foreach
循环中复制和修改
$seen
的方式看起来有点复杂。用一些已知的测试数据跟踪这个,你可能会在这里发现一个bug。好的,我将使用深度设置来尝试这个,我想我应该在每一页上睡觉(2)。我会发布结果。