调用python对象时超出了递归深度

2024-04-18 09:56:02 发布

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

我正在制作一个网络爬虫,我使用以下两个功能:

#Each queued link is the new job
def create_jobs():
    for link in file_to_set(QUEUE_FILE):
        queue.put(link)
    queue.join()
    crawl()

#Check if there are items in the queue then solve them
def crawl():
    queued_links = file_to_set(QUEUE_FILE)
    if len(queued_links)>0:
        print(str(len(queued_links))+' links in the queue')
        create_jobs()

在这里爬行被称为第一。有时在抓取页面时,它会显示超出了最大递归深度,而有时不会。(我再次运行相同的脚本)。有人能解释一下有什么问题吗?你知道吗

请注意,我需要爬网的链接数量只有100个左右,这比python的限制要少。你知道吗


Tags: thetoinqueuedefcreatejobslink
2条回答

函数crawl调用再次调用create_jobscrawl。因此,如果不确定停止条件(len(queued_links == 0),则可能进入无限循环,或者达到Python递归限制。你知道吗

create_jobs中,您正在调用crawl,如果只是这样就可以了。但是由于您也在从crawl调用create_jobs,所以您可能会进入一个无限循环。如果没有条件len(queued_links) > 0,它将是一个无限循环。为了防止此类问题(避免堆栈溢出),python有一个递归限制(请参见:What is the maximum recursion depth in Python, and how to increase it?)。你知道吗

这里的问题是,一个网页很可能包含指向其他网页的链接,因此停止循环的情况不会经常发生。这就是为什么要达到递归极限。您可以通过执行以下操作来增加此限制(此处获取的代码片段:Python: Maximum recursion depth exceeded),但我不建议您这样做:

import sys
sys.setrecursionlimit(10000) # 10000 is an example, try with different values

解决这个问题的好方法是将算法的设计改成这样(基本上是在爬行时对填充的数组进行迭代,而不是进行递归调用):

def crawl(url):
    return [url+'a', url+'b']

links = ['foo', 'bar']
for link in links:
    links.extend(crawl(link))

考虑到算法有时有效有时无效的事实,页面很可能会随着时间的推移而改变,如果您真的接近递归限制,那么根据生成的页面,您是否达到了该限制可能会告诉我。你知道吗

最后,并不是因为只有100个链接,所以不能达到1000个递归限制。事实上,比如你的爬网函数会调用其他函数,等等。。。有些递归是隐藏的。你知道吗

相关问题 更多 >