在构建网络蜘蛛时,你应该使用递归吗?

时间:2009-11-25 11:22:29

标签: ruby

构建深度优先的网络蜘蛛,意味着它将访问首页上的所有链接,并转到每个链接,并访问所有第二页上的链接...

你应该使用递归吗?我发现这是cpu密集型。

def recursion()

linkz_on_first_page.each do |link|

recursion(link)

end
end
recursion(firstpage)

3 个答案:

答案 0 :(得分:12)

绝对不是,由于万维网的实际性质,你很快就会遇到问题。第二个你点击一个主导航部分的网站,每个页面链接到另一个页面,你进入了一个无限循环。

你可以跟踪你已经处理过哪些链接,但即便如此,递归循环并不真正适合万维网的性质(尽管起初看起来似乎是网络更像是一个实际的“网“比一棵树”。您最好找到当前页面上的所有链接,并将这些链接(如果它们尚不存在)添加到中央队列,并在您到达时逐步处理每个链接的队列(请记住跟踪您已完成处理的链接,或者您将它们再次添加到队列的末尾)

答案 1 :(得分:4)

递归似乎是合适的 - 直到你再多想一想它。 如果您有一个包含指向页面B的链接的页面A和包含指向页面A的链接的页面B,那么您将陷入无休止的循环中。

递归不再是以“正常”方式执行的CPU密集型操作。您必须问自己是否需要所有链接,或者只需将链接下载到某个级别就足够了。在后一种情况下,这也解决了你无休止的循环问题。

如果您需要所有链接,我宁愿使用链接列表,其中每个链接都是唯一的。您的程序从列表和蜘蛛链接获取链接。一旦发现新链接,您就会尝试将其插入此列表中,依此类推。

答案 2 :(得分:1)

并不是说递归是CPU密集型的(事实并非如此),但更多的是你会在几千次递归调用之后炸毁你的调用堆栈 - 你很容易在编写一个在开放的互联网上运行的网络蜘蛛

示例:

def blow_stack(level=0)
  puts "at level #{level}"
  blow_stack(level+1)
end

在Macbook Pro上输出:

irb(main):009:0> blow_stack
at level 0
at level 1
... (skip a bunch of output)
at level 6295
at level 6296
SystemStackError: stack level too deep
        from (irb):7:in `blow_stack'
        from (irb):7:in `blow_stack'
        from (irb):9
        from :0