如何在Python/Django中进行HTML编码解码?
我有一个字符串,它是经过HTML编码的:
'''<img class="size-medium wp-image-113"\
style="margin-left: 15px;" title="su1"\
src="http://blah.org/wp-content/uploads/2008/10/su1-300x194.jpg"\
alt="" width="300" height="194" />'''
我想把它改成:
<img class="size-medium wp-image-113" style="margin-left: 15px;"
title="su1" src="http://blah.org/wp-content/uploads/2008/10/su1-300x194.jpg"
alt="" width="300" height="194" />
我希望这个字符串能被当作HTML来处理,这样浏览器就能把它显示成图片,而不是当作文本来显示。
这个字符串之所以是这样的格式,是因为我在使用一个叫做 BeautifulSoup
的网页抓取工具,它会“扫描”网页并获取特定的内容,然后以这种格式返回字符串。
我已经找到了在 C# 中怎么做,但在 Python 中还没找到。有没有人能帮帮我?
相关链接
15 个回答
81
在处理HTML编码时,可以使用标准库里的cgi.escape这个工具:
>> help(cgi.escape)
cgi.escape = 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.
而在进行HTML解码时,我会使用下面的代码:
import re
from htmlentitydefs import name2codepoint
# for some reason, python 2.5.2 doesn't have this one (apostrophe)
name2codepoint['#39'] = 39
def unescape(s):
"unescape HTML code refs; c.f. http://wiki.python.org/moin/EscapingHtml"
return re.sub('&(%s);' % '|'.join(name2codepoint),
lambda m: unichr(name2codepoint[m.group(1)]), s)
如果遇到更复杂的情况,我会用BeautifulSoup这个库。
172
使用标准库:
HTML 转义
try: from html import escape # python 3.x except ImportError: from cgi import escape # python 2.x print(escape("<"))
HTML 反转义
try: from html import unescape # python 3.4+ except ImportError: try: from html.parser import HTMLParser # python 3.x (<3.4) except ImportError: from HTMLParser import HTMLParser # python 2.x unescape = HTMLParser().unescape print(unescape(">"))
142
在Django的使用场景中,有两个答案可以参考。这里有一个关于django.utils.html.escape
函数的例子,供你参考:
def escape(html):
"""Returns the given HTML with ampersands, quotes and carets encoded."""
return mark_safe(force_unicode(html).replace('&', '&').replace('<', '&l
t;').replace('>', '>').replace('"', '"').replace("'", '''))
要反转这个过程,Jake的回答中提到的Cheetah函数应该可以用,但它缺少了单引号。这一版本更新了元组,替换的顺序也进行了调整,以避免对称性的问题:
def html_decode(s):
"""
Returns the ASCII decoded version of the given HTML string. This does
NOT remove normal HTML tags like <p>.
"""
htmlCodes = (
("'", '''),
('"', '"'),
('>', '>'),
('<', '<'),
('&', '&')
)
for code in htmlCodes:
s = s.replace(code[1], code[0])
return s
unescaped = html_decode(my_string)
不过,这并不是一个通用的解决方案;它只适用于用django.utils.html.escape
编码的字符串。更一般来说,最好还是使用标准库:
# Python 2.x:
import HTMLParser
html_parser = HTMLParser.HTMLParser()
unescaped = html_parser.unescape(my_string)
# Python 3.x:
import html.parser
html_parser = html.parser.HTMLParser()
unescaped = html_parser.unescape(my_string)
# >= Python 3.5:
from html import unescape
unescaped = unescape(my_string)
作为一个建议:将HTML以未转义的形式存储在数据库中可能更合理。如果可能的话,值得考虑从BeautifulSoup获取未转义的结果,这样可以完全避免这个过程。
在Django中,转义只发生在模板渲染的时候;所以要防止转义,你只需要告诉模板引擎不要转义你的字符串。要做到这一点,可以在你的模板中使用以下选项:
{{ context_var|safe }}
{% autoescape off %}
{{ context_var }}
{% endautoescape %}