Python:调用Python对象时超出了最大递归深度
我建立了一个必须在大约500万个页面上运行的搜寻器(通过增加url ID),然后解析包含我需要的信息的页面。
使用在网址(200K)上运行并保存好坏结果的算法后,我发现我在浪费大量时间。我可以看到有一些返回的子代换代码,可用于检查下一个有效的URL。
您可以很快地看到子交易(一些最初的“好ID”的前几位)
510000011 # +8510000029 # +18
510000037 # +8
510000045 # +8
510000052 # +7
510000060 # +8
510000078 # +18
510000086 # +8
510000094 # +8
510000102 # +8
510000110 # etc'
510000128
510000136
510000144
510000151
510000169
510000177
510000185
510000193
510000201
在抓取大约200K网址后,我只得到了14K好的结果,我知道我在浪费时间,需要对其进行优化,因此我运行了一些统计信息,并构建了一个函数来检查网址,同时使用8
\ 18 \ 17 \来增加id 8(返回的最差子)等。
这是功能-
def checkNextID(ID): global numOfRuns, curRes, lastResult
while ID < lastResult:
try:
numOfRuns += 1
if numOfRuns % 10 == 0:
time.sleep(3) # sleep every 10 iterations
if isValid(ID + 8):
parseHTML(curRes)
checkNextID(ID + 8)
return 0
if isValid(ID + 18):
parseHTML(curRes)
checkNextID(ID + 18)
return 0
if isValid(ID + 7):
parseHTML(curRes)
checkNextID(ID + 7)
return 0
if isValid(ID + 17):
parseHTML(curRes)
checkNextID(ID + 17)
return 0
if isValid(ID+6):
parseHTML(curRes)
checkNextID(ID + 6)
return 0
if isValid(ID + 16):
parseHTML(curRes)
checkNextID(ID + 16)
return 0
else:
checkNextID(ID + 1)
return 0
except Exception, e:
print "somethin went wrong: " + str(e)
基本的作用是-checkNextID(ID)正在获取包含数据减去8的第一个ID,因此第一次迭代将匹配第一个“ if
isValid”子句(isValid(ID + 8)将返回True)。
是一个变量,该变量保存最后一个已知的URL ID,因此我们将运行直到numOfRuns为
是一个获取ID +子代数之一的函数,如果该URL包含我需要的内容,则返回True,并将该URL的汤对象保存到名为’
‘ 的全局变量中,如果该URL不 ,则返回False没有包含我需要的数据。
是一个获取汤对象(curRes),解析我需要的数据,然后将数据保存到csv,然后返回True的函数。
如果isValid()返回True,我们将调用parseHTML(),然后尝试检查下一个ID +
subtrahends(通过调用checkNextID(ID +
subtrahends)),如果它们都不返回我要查找的内容,将其增加1,然后再次检查,直到找到下一个有效网址。
您可以在此处查看其余代码
运行代码后,我得到了大约950个好的结果,并突然引发了异常-
“出了点问题:调用Python对象时超出了最大递归深度”
我可以在WireShark上看到scipt卡在id上-510009541(我用510000003启动了我的脚本),该脚本尝试几次获取具有该ID的url,然后才注意到该错误并停止了该错误。
我真的很高兴看到我得到了相同的结果,但是比我的旧脚本快25到40倍,并且HTTP请求减少了,这非常准确,我错过了1000个好结果中只有1个结果,这是我发现的,不可能朗读5M次,我的旧脚本运行了30个小时,而新脚本在5-10分钟内给我960〜的结果时,我得到了14-15K的结果。
我读到了有关堆栈限制的信息,但是对于要在Python中实现的算法必须有一个解决方案(我不能回到原来的 “算法” ,永远不会结束)。
谢谢!
回答:
这将递归变成一个循环:
def checkNextID(ID): global numOfRuns, curRes, lastResult
while ID < lastResult:
try:
numOfRuns += 1
if numOfRuns % 10 == 0:
time.sleep(3) # sleep every 10 iterations
if isValid(ID + 8):
parseHTML(curRes)
ID = ID + 8
elif isValid(ID + 18):
parseHTML(curRes)
ID = ID + 18
elif isValid(ID + 7):
parseHTML(curRes)
ID = ID + 7
elif isValid(ID + 17):
parseHTML(curRes)
ID = ID + 17
elif isValid(ID+6):
parseHTML(curRes)
ID = ID + 6
elif isValid(ID + 16):
parseHTML(curRes)
ID = ID + 16
else:
ID = ID + 1
except Exception, e:
print "somethin went wrong: " + str(e)
以上是 Python:调用Python对象时超出了最大递归深度 的全部内容, 来源链接: utcz.com/qa/424319.html