【问题标题】:'list' object has no attribute 'items' in Python's BeautifulSoup renderContents'list' 对象在 Python 的 BeautifulSoup renderContents 中没有属性 'items'
【发布时间】:2012-08-12 07:35:41
【问题描述】:

为了从输入中删除不需要/不安全的标签和属性,我使用了以下代码(几乎完全由http://djangosnippets.org/snippets/1655/ 编写):

def html_filter(value, allowed_tags = 'p h1 h2 h3 div span a:href:title img:src:alt:title table:cellspacing:cellpadding th tr td:colspan:rowspan ol ul li br'):
    js_regex = re.compile(r'[\s]*(&#x.{1,7})?'.join(list('javascript')))
    allowed_tags = [tag.split(':') for tag in allowed_tags.split()]
    allowed_tags = dict((tag[0], tag[1:]) for tag in allowed_tags)
    soup = BeautifulSoup(value)
    for comment in soup.findAll(text=lambda text: isinstance(text, Comment)):
        comment.extract()
    for tag in soup.findAll(True):
        if tag.name not in allowed_tags:
            tag.hidden = True
        else:
            tag.attrs = [(attr, js_regex.sub('', val)) for attr, val in tag.attrs.items() if attr in allowed_tags[tag.name]]
    return soup.renderContents().decode('utf8')

它适用于不需要的或列入白名单的标签、未列入白名单的属性,甚至是格式错误的 html。但是,如果存在任何列入白名单的属性,则会引发

'list' object has no attribute 'items'

在最后一行,这对我没有多大帮助。 type(soup)<class 'bs4.BeautifulSoup'> 不管它是否引发错误,所以我不知道它指的是什么。

Traceback:
[...]
File "C:\Users\Mark\Web\www\fnwidjango\src\base\functions\html_filter.py" in html_filter
  30.     return soup.renderContents().decode('utf8')
File "C:\Python27\lib\site-packages\bs4\element.py" in renderContents
  1098.             indent_level=indentLevel, encoding=encoding)
File "C:\Python27\lib\site-packages\bs4\element.py" in encode_contents
  1089.         contents = self.decode_contents(indent_level, encoding, formatter)
File "C:\Python27\lib\site-packages\bs4\element.py" in decode_contents
  1074.                                   formatter))
File "C:\Python27\lib\site-packages\bs4\element.py" in decode
  1021.             indent_contents, eventual_encoding, formatter)
File "C:\Python27\lib\site-packages\bs4\element.py" in decode_contents
  1074.                                   formatter))
File "C:\Python27\lib\site-packages\bs4\element.py" in decode
  1021.             indent_contents, eventual_encoding, formatter)
File "C:\Python27\lib\site-packages\bs4\element.py" in decode_contents
  1074.                                   formatter))
File "C:\Python27\lib\site-packages\bs4\element.py" in decode
  1021.             indent_contents, eventual_encoding, formatter)
File "C:\Python27\lib\site-packages\bs4\element.py" in decode_contents
  1074.                                   formatter))
File "C:\Python27\lib\site-packages\bs4\element.py" in decode
  983.             for key, val in sorted(self.attrs.items()):

Exception Type: AttributeError at /"nieuws"/article/3-test/
Exception Value: 'list' object has no attribute 'items'

【问题讨论】:

  • 你确定tag.attrs 不应该是字典吗? (一开始是一个,你把它改成了一个列表)
  • 我正试图记住我为什么要更改它...到目前为止,当我将其更改回来时,似乎没有任何损坏,可能是我的大脑出现了故障。

标签: python django beautifulsoup html-sanitizing


【解决方案1】:

尝试替换

tag.attrs = [(attr, js_regex.sub('', val)) for attr, val in tag.attrs.items() if attr in allowed_tags[tag.name]]

tag.attrs = dict((attr, js_regex.sub('', val)) for attr, val in tag.attrs.items() if attr in allowed_tags[tag.name])

【讨论】:

    【解决方案2】:

    看起来renderContents() 期望您将attrs 设置为dict(这将具有items 方法),而不是您传递的元组列表。因此,当它尝试访问它时会抛出AttributeError

    要修复错误,您可以在 Python 3 中使用字典推导:

    tag.attrs = {attr: js_regex.sub('', val)) for attr, val in tag.attrs.items() if attr in allowed_tags[tag.name]}
    

    在 Python 2 中,不支持 dict 推导式,因此您应该将迭代器传递给 dict 构造函数:

    tag.attrs = dict((attr, js_regex.sub('', val)) for attr, val in tag.attrs.items() if attr in allowed_tags[tag.name]))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-17
      • 2015-09-30
      • 2020-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      • 2013-09-22
      相关资源
      最近更新 更多