url的Python递归爬网

2024-05-14 09:33:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一种方法,当提供链接列表时,将获得子链接,依此类推:

def crawlSite(self, linksList):
    finalList = []
    for link in list(linksList):
        if link not in finalList:
            print link            
            finalList.append(link)
            childLinks = self.getAllUniqueLinks(link)
            length = len(childLinks)
            print 'Total links for this page: ' + str(length)

        self.crawlSite(childLinks)
    return finalList

它最终会用同一组链接重复它自己,我似乎搞不懂。当我在if语句中移动self.crawlSite(childLinks)时。我把单子上的第一项一遍又一遍地重复。在

背景self.getAllUniqueLinks(link)方法从给定页面获取链接列表。它过滤给定域中所有可单击的链接。基本上,我要做的是从一个网站获得所有可点击的链接。如果这不是理想的方法。你能推荐一种更好的方法来做同样的事情吗。还请考虑一下,我对python相当陌生,可能不了解更复杂的方法。所以请解释一下你的思维过程。如果你不介意的话:)


Tags: 方法inself列表forif链接link
2条回答

您正在清除每个递归调用上的finalLinks数组。在

现在需要的是一组更全局的链接,你已经访问过了。每个递归调用都应该有助于这个全局列表,否则,如果您的图有循环,您最终肯定会访问一个站点两次。在

更新:查看DFS on a graph using a python generator中使用的nice模式。您的finalList可以是参数,默认值为[]。在每次递归调用中添加到此列表。另外,FWIW,考虑一个set而不是list-它更快。在

你需要

finalList.extend(self.crawlSite(childLinks))

不仅仅是

^{pr2}$

您需要将内部crawlSite()返回的列表与外部crawlSite()中已有的列表合并。即使它们都被称为finalList,但在每个作用域中都有一个不同的列表。在

另一种(也是更好的)解决方案是让finalList成为一个实例变量(或某种类型的非局部变量),而不仅仅是一个局部变量,这样它就被crawlSite()s的所有作用域共享:

def __init__(self, *args, **kwargs):
    self.finalList = set()

def crawlSite(self, linksList):
    for link in linksList:
        if link not in self.finalList:
            print link            
            self.finalList.add(link)
            childLinks = self.getAllUniqueLinks(link)
            length = len(childLinks)
            print 'Total links for this page: ' + str(length)
            self.crawlSite(childLinks)

如果您想用同一个实例从头开始,只需确保self.finalList = []。在

编辑:通过将递归调用放在if块中修复了代码。用了一套。另外,linksList不需要是一个列表,只需要一个iterable对象,因此从for循环中删除了list()调用。这是由@Ray Toal建议的

相关问题 更多 >

    热门问题