Как я выполняю декодирование/кодирование HTML с помощью Python/Django?

121
задан daaawx 21 April 2019 в 00:04
поделиться

7 ответов

Учитывая вариант использования 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('&', '&amp;').replace('<', '&l
t;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;'))

Для инвертирования это, функция Гепарда, описанная в ответе Jake's, должно работать, но пропускает одинарную кавычку. Эта версия включает обновленный кортеж с порядком замены, инвертированной для предотвращения симметричных проблем:

def html_decode(s):
    """
    Returns the ASCII decoded version of the given HTML string. This does
    NOT remove normal HTML tags like <p>.
    """
    htmlCodes = (
            ("'", '&#39;'),
            ('"', '&quot;'),
            ('>', '&gt;'),
            ('<', '&lt;'),
            ('&', '&amp;')
        )
    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 %}
111
ответ дан nuts 24 November 2019 в 01:28
поделиться

Я нашел это в исходном коде Гепарда ( здесь )

htmlCodes = [
    ['&', '&amp;'],
    ['<', '&lt;'],
    ['>', '&gt;'],
    ['"', '&quot;'],
]
htmlCodesReversed = htmlCodes[:]
htmlCodesReversed.reverse()
def htmlDecode(s, codes=htmlCodesReversed):
    """ Returns the ASCII decoded version of the given HTML string. This does
        NOT remove normal HTML tags like <p>. It is the inverse of htmlEncode()."""
    for code in codes:
        s = s.replace(code[1], code[0])
    return s

не уверенным, почему они инвертируют список, я думаю, что это имеет отношение к способу, которым они кодируют, таким образом, с Вами это, возможно, не должно быть инвертировано. Также на вашем месте я изменил бы htmlCodes, чтобы быть списком кортежей, а не списком списков..., это входит в мою библиотеку хотя:)

я заметил, что Ваш заголовок, который попросили относительно, кодирует также, таким образом, вот Гепард, кодируют функцию.

def htmlEncode(s, codes=htmlCodes):
    """ Returns the HTML encoded version of the given string. This is useful to
        display a plain ASCII text string on a web page."""
    for code in codes:
        s = s.replace(code[0], code[1])
    return s
1
ответ дан Jake 24 November 2019 в 01:28
поделиться

Посмотрите у основания этого страница в Python wiki, существует по крайней мере 2 опции "не выйти" из HTML.

8
ответ дан zgoda 24 November 2019 в 01:28
поделиться

Используйте решение daniel, если набор закодированных символов относительно ограничивается. Иначе пользуйтесь одной из многочисленных анализирующих HTML библиотек.

мне нравится BeautifulSoup, потому что он может обработать уродливый XML/HTML:

http://www.crummy.com/software/BeautifulSoup/

для Вашего вопроса, существует пример в их документация

from BeautifulSoup import BeautifulStoneSoup
BeautifulStoneSoup("Sacr&eacute; bl&#101;u!", 
                   convertEntities=BeautifulStoneSoup.HTML_ENTITIES).contents[0]
# u'Sacr\xe9 bleu!'
20
ответ дан vincent 24 November 2019 в 01:28
поделиться

Для кодирования 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.

80
ответ дан Maik Hoepfel 24 November 2019 в 01:28
поделиться

Комментарий Даниэля в качестве ответа:

«Экранирование происходит в Django только во время рендеринга шаблона. Следовательно, в этом нет необходимости - вы просто указываете движку шаблонов не ускользать. { {context_var | safe}} или {% autoescape off%} {{context_var}} {% endautoescape%} "

6
ответ дан 24 November 2019 в 01:28
поделиться

Я нашел прекрасную функцию по адресу: http://snippets.dzone.com/posts/show/4569

def decodeHtmlentities(string):
    import re
    entity_re = re.compile("&(#?)(\d{1,5}|\w{1,8});")

    def substitute_entity(match):
        from htmlentitydefs import name2codepoint as n2cp
        ent = match.group(2)
        if match.group(1) == "#":
            return unichr(int(ent))
        else:
            cp = n2cp.get(ent)

            if cp:
                return unichr(cp)
            else:
                return match.group()

    return entity_re.subn(substitute_entity, string)[0]
5
ответ дан 24 November 2019 в 01:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: