我希望能够以递归方式从网站获取所有链接,然后按照这些链接获取这些网站的所有链接。深度应为5-10,以便返回它找到的所有链接的数组。最好使用美丽的汤/蟒蛇。谢谢!
到目前为止,我已经尝试了这个并且它无法工作......任何帮助都将受到赞赏。
from BeautifulSoup import BeautifulSoup
import urllib2
def getLinks(url):
if (len(url)==0):
return [url]
else:
files = [ ]
page=urllib2.urlopen(url)
soup=BeautifulSoup(page.read())
universities=soup.findAll('a',{'class':'institution'})
for eachuniversity in universities:
files+=getLinks(eachuniversity['href'])
return files
print getLinks("http://www.utexas.edu/world/univ/alpha/")
答案 0 :(得分:4)
抓取页面的数量将呈指数级增长,涉及的许多问题在初看时可能看起来并不复杂,请查看scrapy架构概述,以了解在现实生活中应该如何完成3 p>
除了其他强大的功能之外,scrapy不会重复抓取相同的网页(除非您强制执行)并且可以配置为最大DEPTH_LIMIT
更好的是,scrapy有一个内置的链接提取工具link-extractors
答案 1 :(得分:1)
递归算法用于将大问题减少到具有相同结构的较小问题,然后将结果组合起来。它们通常由不会导致递归的基本情况和导致递归的另一种情况组成。例如,假设您出生于1986年,并且您想要计算您的年龄。你可以写:
def myAge(currentyear):
if currentyear == 1986: #Base case, does not lead to recursion.
return 0
else: #Leads to recursion
return 1+myAge(currentyear-1)
我,我自己,并没有真正看到在你的问题中使用递归的重点。我的建议是你首先在代码中设置一个限制。你给我们的东西只会无限地运行,因为程序会陷入无限嵌套的for循环中;它永远不会达到目的并开始回归。因此,您可以在函数外部使用一个变量,每次进入某个级别时都会更新,并且在某个时刻停止该函数启动新的for循环并开始返回它所找到的内容。
但是你开始改变全局变量,你会以一种奇怪的方式使用递归,而代码会变得混乱。
现在阅读评论并选择你真正想要的东西,我必须说,这不是很清楚,你可以在你的代码中使用递归算法的帮助,但不能递归写出所有这些。
def recursiveUrl(url,depth):
if depth == 5:
return url
else:
page=urllib2.urlopen(url)
soup = BeautifulSoup(page.read())
newlink = soup.find('a') #find just the first one
if len(newlink) == 0:
return url
else:
return url, recursiveUrl(newlink,depth+1)
def getLinks(url):
page=urllib2.urlopen(url)
soup = BeautifulSoup(page.read())
links = soup.find_all('a', {'class':'institution'})
for link in links:
links.append(recursiveUrl(link,0))
return links
现在仍然存在这样的问题:链接并不总是链接到网页,而是链接到文件和图像。这就是我在'url-opening'函数的递归部分编写if / else语句的原因。另一个问题是你的第一个网站有2166个机构链接,创建2166 * 5个漂亮的东西并不快。上面的代码运行2166次递归函数。这不应该是一个问题,但你正在处理大的html(或任何PHP)文件,所以制作2166 * 5的汤需要花费大量的时间。