Beautifulsoup,最大递归深度已达到

6

这是一个使用 beautifulsoup 抓取所有 <p> html 标签内容的过程。在从一些网页中抓取内容后,我收到了一个报错信息,提示递归深度超出最大限制。

def printText(tags):
    for tag in tags:
        if tag.__class__ == NavigableString:
            print tag,
        else:
            printText(tag)
    print ""
#loop over urls, send soup to printText procedure

跟踪的底部:
 File "web_content.py", line 16, in printText
    printText(tag)
  File "web_content.py", line 16, in printText
    printText(tag)
  File "web_content.py", line 16, in printText
    printText(tag)
  File "web_content.py", line 16, in printText
    printText(tag)
  File "web_content.py", line 16, in printText
    printText(tag)
  File "web_content.py", line 13, in printText
    if tag.__class__ == NavigableString:
RuntimeError: maximum recursion depth exceeded in cmp
3个回答

5

如果printText()遇到的不是NavigableString,包括NavigableString的子类(例如Comment),它会递归调用自己。在Comment上调用printText()会迭代注释的文本,并导致您看到的无限递归。

我建议在if语句中使用isinstance()而不是比较类对象:

if isinstance(tag, basestring):

我通过在递归之前插入打印语句来诊断这个问题:
print "recursing on", tag, type(tag)
printText(tag)

1

你可能遇到了一个字符串。在字符串上进行迭代会产生长度为1的字符串。在那个长度为1的字符串上进行迭代会产生另一个长度为1的字符串。在那个长度为1的字符串上进行迭代...


你能解释一下吗?这是之前一个 URL 崩溃前的样本输出。"曾经需要两个月的过程,现在对于许多公司来说只需要五天的时间。筹集 100 万到 200 万美元的问题在于可转换债券中包含字符串,以及长度为 1 的字符串。" - yayu
你不明白的是迭代还是迭代?当然,这完全取决于你是否理解代码的工作原理。 - Ignacio Vazquez-Abrams
1
你能澄清一下“你击中了一个字符串”是什么意思吗?你所说的“击中”是什么意思?难道最初由Beautiful Soup解析为DOM的整个HTML文档不是一个字符串吗?标签本身不也是字符的字符串吗?我们在尝试将值替换为一个简单的HTML页面中的12个锚点时遇到了相同的错误,但不清楚是什么触发了递归。 - Praxiteles
@Praxiteles:DOM文档由节点组成。其中一些节点是标签,而另一些节点是文本。如果你尝试对文本进行递归,即字符串,那么会无限递归,因为迭代非空字符串至少会产生一个字符串。 - Ignacio Vazquez-Abrams

1
我遇到了同样的问题。如果您有嵌套标签,深度约为480级,并且您想将此标签转换为字符串/ Unicode,则会收到“RuntimeError maximum recursion depth reached”的错误。每个级别都需要两个嵌套方法调用,很快就会达到1000个默认Python调用的嵌套限制。您可以提高这个级别,或者您可以使用此辅助程序。它从HTML中提取所有文本并在预设环境中显示文本。
def beautiful_soup_tag_to_unicode(tag):
    try:
        return unicode(tag)
    except RuntimeError as e:
        if not str(e).startswith('maximum recursion'):
            raise
        # If you have more than 480 level of nested tags you can hit the maximum recursion level
        out=[]
        for mystring in tag.findAll(text=True):
            mystring=mystring.strip()
            if not mystring:
                continue
            out.append(mystring)
        return u'<pre>%s</pre>' % '\n'.join(out)

7
sys.setrecursionlimit(1500) - guettli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接