我有这种方法,当提供链接列表时,将获得子链接,依此类推:
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相当新,可能不了解更复杂的方法。所以请解释你的思考过程。如果你不介意:)
答案 0 :(得分:3)
你需要
finalList.extend(self.crawlSite(childLinks))
不仅仅是
self.crawlSite(childLinks)
您需要将内部crawlSite()
返回的列表与外部crawlSite()
中已存在的列表合并。尽管它们都被称为finalList
,但每个范围内都有不同的列表。
替代(和更好)的解决方案是让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
不一定是列表,只是一个可迭代对象,因此从list()
循环中删除了for
调用。套装由@ Ray-Toal
答案 1 :(得分:2)
您正在清除每个递归调用的finalLinks
数组。
您需要的是一组您已访问过的更全球化的链接。每个递归调用都应该对这个全局列表有所贡献,否则,如果你的图表有周期,你肯定最终会访问一个站点两次。
更新:查看DFS on a graph using a python generator中使用的漂亮模式。您的finalList
可以是参数,默认值为[]
。在每个递归调用中添加到此列表。另外,FWIW,考虑set
而不是list
---它更快。