繁体   English   中英

Python 递归爬取url

[英]Python recursive crawling for urls

我有这种方法,当提供链接列表时,将获取子链接等等:

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 相当陌生,可能不了解更复杂的方法。 所以请解释一下你的思维过程。 如果你不介意:)

你需要

finalList.extend(self.crawlSite(childLinks))

不只是

self.crawlSite(childLinks)

您需要将内部crawlSite()返回的列表与外部crawlSite()中已经存在的列表合并。 尽管它们都称为finalList ,但每个 scope 中都有不同的列表。

另一种(更好的)解决方案是让 finalList 成为实例变量(或某种类型的非局部变量),而不仅仅是一个局部变量,以便它由crawlSite()的所有范围共享:

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不需要是一个列表,只是一个可迭代的 object,因此从for循环中删除了list()调用。 Set 由@Ray-Toal 建议

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

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

更新: 使用 python 生成器在图表上查看 DFS 中使用的漂亮模式。 您的finalList可以是一个参数,默认值为[] 在每个递归调用中添加到此列表。 此外,FWIW,考虑一个set而不是一个list ——它更快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM