什么';在Python中转义HTML的最简单方法是什么?

什么';在Python中转义HTML的最简单方法是什么?,python,html,Python,Html,cgi.escape似乎是一个可能的选择。它工作得好吗?有什么被认为更好的吗?可以。它逃避了: 至 &至& 这对于所有HTML来说已经足够了 编辑:如果您有非ascii字符,您也希望转义,以便包含在另一个使用不同编码的编码文档中,如Craig所说,只需使用: data.encode('ascii', 'xmlcharrefreplace') 不要忘了先将数据解码为unicode,使用编码的任何编码 然而,根据我的经验,如果您从一开始就一直使用unicode,那么这种编码是无用的。只需

cgi.escape似乎是一个可能的选择。它工作得好吗?有什么被认为更好的吗?

可以。它逃避了:

  • &
    &
这对于所有HTML来说已经足够了

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

data.encode('ascii', 'xmlcharrefreplace')
不要忘了先将
数据
解码为
unicode
,使用编码的任何编码

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

例如:

>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'&lt;a&gt;b&#225;&lt;/a&gt;
>>cgi.escape(u',除了
quote
默认为True之外,它的作用相同。

在转义HTML标记和字符实体的有限意义上,转义HTML应该是很好的

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

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

它有一个函数
escape()

导入html >>>escape('x>2&&x<7单引号:\'双引号:') 'x2&;x7单引号:&x27;双引号:'
如果希望在URL中转义HTML:

这可能不是OP想要的(问题并没有明确指出转义应该在哪个上下文中使用),但是Python的本机库有一种方法可以转义需要安全地包含在URL中的HTML实体

以下是一个例子:

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

x = '+<>^&'
print quote(x) # prints '%2B%3C%3E%5E%26'
!/usr/bin/python
从urllib导入报价
x='+^&'
打印报价(x)#打印“%2B%3C%3E%5E%26”

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;')
def escape_html(文本):
“”“用于在HTML中显示的转义字符串”“”
返回cgi.escape(text,quote=True)\
替换(u'\n',u'
')\ 替换(u'\t',u'&emsp;')\ 替换(u“”,u“”)
例如
>>转义html('\nfoo\t“bar'))
u'foo
foo&emsp;“bar”
对于Python 2.7中的遗留代码,可以通过以下方式完成:


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

转义版本

def转义(s,quote=None):
将“特殊字符”和“替换为HTML安全序列”。
如果可选标志引号为true,则引号字符(“”)
也是翻译过来的
s=s。必须先进行替换(“&”、“&;”)#!
s=s。替换(“,”)
如果引用:
s=s.replace(“”,“”)
返回s
正则表达式版本

QUOTE|u PATTERN=r”“([&“)(?!(lt | gt | quot|39)”)
def转义(word):
"""
将特殊字符&“”替换为HTML安全序列。
注意已经转义的字符。
"""
将_替换为={
'': '',
“&”:“&;”,
“”:“”,#应在属性中转义
“'”:“''#应在属性中转义
}
quote\u模式=重新编译(quote\u模式)
返回re.sub(引用\u模式,lambda x:将\u替换为[x.group(0)],word)

还有一个很好的例子

>>从markupsafe导入标记,转义
>>>转义(“警报(document.cookie);”)
标记(u'scriptalert(document.cookie);/script')
markupsafe
软件包经过了精心设计,可能是最通用和最适合逃跑的方式,IMHO,因为:

  • 返回(
    Markup
    )是从unicode派生的类(即
    isinstance(escape('str'),unicode)==True
  • 它正确地处理unicode输入
  • 它在Python中工作(2.6、2.7、3.3和pypy)
  • 它尊重对象的自定义方法(即具有
    \uuuuuuhtml\uuuuuu
    属性的对象)和模板重载(
    \uuuuhtml\u format\uuuu

  • 没有任何库(纯python)可以安全地将文本转义为html文本:

    text.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;'
            ).replace('\'','&#39;').replace('"','&#34;').encode('ascii', 'xmlcharrefreplace')
    

    text.replace('&','&;').replace('>','').replace('cgi.escape的附加布尔参数也应考虑用于在HTML属性值中使用文本时转义引号。请确保:如果我通过
    cgi.escape
    函数运行所有不受信任的数据,就足以防止所有(已知)错误XSS attacs?@Tomas Sedovic:取决于运行cgi.escape后将文本放在何处。如果放在根HTML上下文中,那么是的,您是完全安全的。像{Measures 12Ω“H x 17 5/8”W x 8 7/8”D.Imported.}这样的输入是不是ascii的,所以encode()将向您抛出异常。@Andrew Kolesnikov:您尝试过吗?
    cgi.escape(YourUnicodoBj.encode('ascii','xmlcharrefreplace')==='{{度量值12Ω;'hx175/8“wx87/8”D.导入。}“
    --如您所见,表达式返回ascii bytestring,所有非ascii unicode字符使用xml字符引用表编码。这是错误的转义;我们正在寻找,而不是。Nontheless-这正是我实际寻找的;-)那么
    quote=True
    ?@SalmanAbbas您担心引号不会转义吗?请注意
    html.escape()<
    
    >>> escape_html('<foo>\nfoo\t"bar"')
    u'&lt;foo&gt;<br />foo&emsp;&quot;bar&quot;'
    
    >>> bs4.dammit import EntitySubstitution
    >>> esub = EntitySubstitution()
    >>> esub.substitute_html("r&d")
    'r&amp;d'
    
    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)
    
    >>> from markupsafe import Markup, escape
    >>> escape("<script>alert(document.cookie);</script>")
    Markup(u'&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
    
    text.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;'
            ).replace('\'','&#39;').replace('"','&#34;').encode('ascii', 'xmlcharrefreplace')