在Python中逃避HTML的最简单方法是什么?

时间:2009-06-30 04:15:54

标签: python html

cgi.escape似乎是一种可能的选择。它运作良好吗?有没有被认为更好的东西?

9 个答案:

答案 0 :(得分:173)

cgi.escape没问题。它逃脱了:

  • <&lt;
  • >&gt;
  • &&amp;

这对所有HTML都足够了。

编辑:如果您有非ascii字符,您也想要转义,包含在另一个使用不同编码的编码文档中,如 Craig 所说,只需使用:

data.encode('ascii', 'xmlcharrefreplace')

不要忘记首先使用编码的任何编码将data解码为unicode

但是根据我的经验,如果你从一开始就一直使用unicode,那么这种编码就没用了。只需在文档标题(utf-8)中指定的编码的末尾进行编码,以获得最大的兼容性。

示例:

>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'&lt;a&gt;b&#225;&lt;/a&gt;

另外值得注意的是(感谢Greg)额外的 quote 参数cgi.escape。设置为True时,cgi.escape也会转义双引号字符("),因此您可以在XML / HTML属性中使用结果值。

编辑:请注意,在Python 3.2中不推荐使用cgi.escape而使用html.escape,除了 quote 默认为True之外,它都是相同的。

答案 1 :(得分:91)

在Python 3.2中引入了一个新的html模块,用于从HTML标记中转义保留字符。

它有一个函数escape()

>>> import html
>>> html.escape('x > 2 && x < 7')
'x &gt; 2 &amp;&amp; x &lt; 7'

答案 2 :(得分:10)

如果您希望在网址中转义HTML:

这可能不是OP想要的(问题并没有清楚地表明在哪个上下文中意图使用转义),但Python的本地库urllib有一个方法来转义需要的HTML实体安全地包含在URL中。

以下是一个例子:

#!/usr/bin/python
from urllib import quote

x = '+<>^&'
print quote(x) # prints '%2B%3C%3E%5E%26'

Find docs here

答案 3 :(得分:8)

cgi.escape在转义HTML标记和字符实体的有限意义上应该很好地逃避HTML。

但您可能还必须考虑编码问题:如果您要引用的HTML在特定编码中具有非ASCII字符,那么您还必须注意在引用时明智地表示这些字符。也许您可以将它们转换为实体。否则,您应确保在“源”HTML及其嵌入的页面之间进行正确的编码转换,以避免破坏非ASCII字符。

答案 4 :(得分:8)

还有优秀的markupsafe package

>>> from markupsafe import Markup, escape
>>> escape("<script>alert(document.cookie);</script>")
Markup(u'&lt;script&gt;alert(document.cookie);&lt;/script&gt;')

markupsafe包装设计精良,可能是最通用和最恐怖的逃避方式,恕我直言,因为:

  1. return(Markup)是一个派生自unicode的类(即isinstance(escape('str'), unicode) == True
  2. 它正确处理unicode输入
  3. 它适用于Python(2.6,2.7,3.3和pypy)
  4. 它尊重对象的自定义方法(即具有__html__属性的对象)和模板重载(__html_format__)。

答案 5 :(得分:3)

没有库,纯python,安全地将文本转义为html文本:

text.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;'
        ).encode('ascii', 'xmlcharrefreplace')

答案 6 :(得分:2)

cgi.escape延长

此版本改进了cgi.escape。它还保留了空格和换行符。返回unicode字符串。

def escape_html(text):
    """escape strings for display in HTML"""
    return cgi.escape(text, quote=True).\
           replace(u'\n', u'<br />').\
           replace(u'\t', u'&emsp;').\
           replace(u'  ', u' &nbsp;')
例如

>>> escape_html('<foo>\nfoo\t"bar"')
u'&lt;foo&gt;<br />foo&emsp;&quot;bar&quot;'

答案 7 :(得分:2)

不是最简单的方法,但仍然很简单。与 cgi.escape 模块的主要区别 - 如果您的文本中已经有&amp;,它仍然可以正常工作。正如你从评论中看到的那样:

cgi.escape version

def escape(s, quote=None):
    '''Replace special characters "&", "<" and ">" to HTML-safe sequences.
    If the optional flag quote is true, the quotation mark character (")
is also translated.'''
    s = s.replace("&", "&amp;") # Must be done first!
    s = s.replace("<", "&lt;")
    s = s.replace(">", "&gt;")
    if quote:
        s = s.replace('"', "&quot;")
    return s

正则表达式

QUOTE_PATTERN = r"""([&<>"'])(?!(amp|lt|gt|quot|#39);)"""
def escape(word):
    """
    Replaces special characters <>&"' to HTML-safe sequences. 
    With attention to already escaped characters.
    """
    replace_with = {
        '<': '&gt;',
        '>': '&lt;',
        '&': '&amp;',
        '"': '&quot;', # should be escaped in attributes
        "'": '&#39'    # should be escaped in attributes
    }
    quote_pattern = re.compile(QUOTE_PATTERN)
    return re.sub(quote_pattern, lambda x: replace_with[x.group(0)], word)

答案 8 :(得分:0)

通过BeautifulSoup4

>>> bs4.dammit import EntitySubstitution
>>> esub = EntitySubstitution()
>>> esub.substitute_html("r&d")
'r&amp;d'