Home  >  Article  >  Backend Development  >  正则抓取天涯数据,递归失败,求解。。。。

正则抓取天涯数据,递归失败,求解。。。。

WBOY
WBOYOriginal
2016-06-23 14:19:02850browse

本帖最后由 liuser_cn 于 2013-08-12 21:25:48 编辑

前言:我的面向对象基础一般。。

我是抓的一个模块(鬼话)。
它的下一页是用时间戳来搞的。
我就想,在抓取第一页的所有标题URL之后,顺便抓取下一页的地址(‘可以抓取’);
现在是,第一页的所有标题的URL抓完了,下一页的URL也抓了,
我想递归100次,抓100页的所有标题的URL。
看代码吧。
   public function getAllPage($url){        /**         * curl_setopt($ch, CURLOPT_FAILONERROR, true);//记录错误信息设置         * curl_errno可以获得错误码,当然也包括错误的http状态码           curl_error可以获得错误信息         */        $ch =  curl_init($url);//初始化一个句柄        curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);        curl_setopt($ch,CURLOPT_TIMEOUT,1111111);        $html = curl_exec($ch);        curl_close($ch);                //修饰一下,从何时开始。        $length     = strpos($html, 'class="mt5');        $newHtml    = substr($html, $length);        //修饰END            $pattern    = "#\/post-.*\.shtml#i"; //正则表达式            preg_match_all($pattern, $newHtml,$matches);            //抓取下一页链接地址            $nextPagePattern   =    "#\<a href=\"(.*)\"\srel#";            preg_match($nextPagePattern, $newHtml,$nextPage);            $nextPageUrl    =   "http://bbs.tianya.cn".$nextPage['1'];            //下一页   END            //链接。全。            foreach($matches['0'] as $k=>$v){                 $matches[$k]   =   'http://bbs.tianya.cn'.$v;            }            //之前的递归是在这里的,一运行直接死掉了。。。。。        return array(            '0'=>$matches,            '1'=>$nextPageUrl,        );    }


我想问一下,这个思路有没有问题?
递归的代码方便给一个么= =!!

回复讨论(解决方案)

foreach($ matches['0'] as $k=>$v){
          $matches[$k]   =   'http://bbs.tianya.cn'.$v;
}

循环中修改数组的意义是什么呢?
你的递归部分的代码也贴出来

foreach($ matches['0'] as $k=>$v){
          $matches[$k]   =   'http://bbs.tianya.cn'.$v;
}

循环中修改数组的意义是什么呢?
你的递归部分的代码也贴出来
1:补全,抓取到的地址没有域名。
2:递归。。。我那个注释之前是这样写的,

for($i=0;$i<100;$i++){  $this->getAllPage($nextPageUrl)             }

for($i=0;$i   $this->getAllPage($nextPageUrl)
}

这么做并不是递归抓取100次。
而是循环了一百次,每次都在执行一个递归函数,而你的递归函数是没有出口的(没有跳出递归的出口,会导致无限递归),当然会死了。

for($i=0;$i   $this->getAllPage($nextPageUrl)
}

这么做并不是递归抓取100次。
而是循环了一百次,每次都在执行一个递归函数,而你的递归函数是没有出口的(没有跳出递归的出口,会导致无限递归),当然会死了。
请赐教?

for($i=0;$i   $this->getAllPage($nextPageUrl)
}

这么做并不是递归抓取100次。
而是循环了一百次,每次都在执行一个递归函数,而你的递归函数是没有出口的(没有跳出递归的出口,会导致无限递归),当然会死了。
出口就是判断么?

对你的需求,可以这么做:
public function getAllPage($url, $depth, &$result)
$depth控制递归的深度,初始为0。 引用型的$result 记录最终的匹配到的结果。

递归的跳出部分:
if($depth == 100){
    return;
}

递归函数的递归部分:
    $nextPageUrl    =   "http://bbs.tianya.cn".$nextPage['1'];
    foreach($matches['0'] as $k=>$v){
        $result[] = 'http://bbs.tianya.cn'.$v;
    }
    getAllPage($nextPageUrl,$depth+1,$result);


递归函数初始调用:
$result = array();
getAllPage($url,0,$result);


for($i=0;$i   $this->getAllPage($nextPageUrl)
}

这么做并不是递归抓取100次。
而是循环了一百次,每次都在执行一个递归函数,而你的递归函数是没有出口的(没有跳出递归的出口,会导致无限递归),当然会死了。
出口就是判断么?

还真不是。你即使去掉循环,只用getAllPage(...)那一部分,也会死的。

对你的需求,可以这么做:
public function getAllPage($url, $depth, &$result)
$depth控制递归的深度,初始为0。 引用型的$result 记录最终的匹配到的结果。

递归的跳出部分:
if($depth == 100){
    return;
}

递归函数的递归部分:
    $nextPageUrl    =   "http://bbs.tianya.cn".$nextPage['1'];
    foreach($matches['0'] as $k=>$v){
        $result[] = 'http://bbs.tianya.cn'.$v;
    }
    getAllPage($nextPageUrl,$depth+1,$result);


递归函数初始调用:
$result = array();
getAllPage($url,0,$result);
多谢!!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn