Как мне выполнить декодирование / кодирование HTML с использованием Python / Django? - PullRequest
116 голосов
/ 08 ноября 2008

У меня есть строка в кодировке 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 ]

1 голос
/ 27 февраля 2012

Вы также можете использовать django.utils.html.escape

from django.utils.html import escape

something_nice = escape(request.POST['something_naughty'])
1 голос
/ 08 ноября 2008

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

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
0 голосов
/ 18 июля 2018

В поисках простейшего решения этого вопроса в Django и Python я обнаружил, что вы можете использовать встроенные их функции для экранирования / отмены кода html.

Пример

Я сохранил ваш HTML-код в scraped_html и clean_html:

scraped_html = (
    '&lt;img class=&quot;size-medium wp-image-113&quot; '
    'style=&quot;margin-left: 15px;&quot; title=&quot;su1&quot; '
    'src=&quot;http://blah.org/wp-content/uploads/2008/10/su1-300x194.jpg&quot; '
    'alt=&quot;&quot; width=&quot;300&quot; height=&quot;194&quot; /&gt;'
)
clean_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" />'
)

Джанго

Вам нужен Django> = 1,0

* 1016 экранирования в * Для удаления вашего очищенного HTML-кода вы можете использовать django.utils.text.unescape_entities , который: Преобразование всех именованных и числовых ссылок на символы в соответствующие символы Юникода. >>> from django.utils.text import unescape_entities >>> clean_html == unescape_entities(scraped_html) True 1027 * бежать * Для выхода из чистого HTML-кода вы можете использовать django.utils.html.escape , который: Возвращает заданный текст с амперсандами, кавычками и угловыми скобками, закодированными для использования в HTML. >>> from django.utils.html import escape >>> scraped_html == escape(clean_html) True Python Вам нужен Python> = 3,4 1044 * экранирования в * Для удаления вашего очищенного HTML-кода вы можете использовать html.unescape , который: Преобразование всех именованных и числовых ссылок (например, &gt;, &#62;, &x3e;) в строке s в соответствующие символы Unicode. >>> from html import unescape >>> clean_html == unescape(scraped_html) True 1058 * побег * Для выхода из чистого HTML-кода вы можете использовать html.escape , который: Преобразование символов &, < и > в строке s в безопасные для HTML последовательности. >>> from html import escape >>> scraped_html == escape(clean_html) True

0 голосов
/ 30 июня 2012

Это самое простое решение для этой проблемы -

{% autoescape on %}
   {{ body }}
{% endautoescape %}

С этой страницы .

0 голосов
/ 15 декабря 2011

Ниже приведена функция Python, которая использует модуль htmlentitydefs. Это не идеально. Имеющаяся у меня версия htmlentitydefs является неполной, и в ней предполагается, что все объекты декодируются в одну кодовую точку, что неправильно для таких объектов, как &NotEqualTilde;:

http://www.w3.org/TR/html5/named-character-references.html

NotEqualTilde;     U+02242 U+00338    ≂̸

С этими предостережениями, вот код.

def decodeHtmlText(html):
    """
    Given a string of HTML that would parse to a single text node,
    return the text value of that node.
    """
    # Fast path for common case.
    if html.find("&") < 0: return html
    return re.sub(
        '&(?:#(?:x([0-9A-Fa-f]+)|([0-9]+))|([a-zA-Z0-9]+));',
        _decode_html_entity,
        html)

def _decode_html_entity(match):
    """
    Regex replacer that expects hex digits in group 1, or
    decimal digits in group 2, or a named entity in group 3.
    """
    hex_digits = match.group(1)  # '&#10;' -> unichr(10)
    if hex_digits: return unichr(int(hex_digits, 16))
    decimal_digits = match.group(2)  # '&#x10;' -> unichr(0x10)
    if decimal_digits: return unichr(int(decimal_digits, 10))
    name = match.group(3)  # name is 'lt' when '&lt;' was matched.
    if name:
        decoding = (htmlentitydefs.name2codepoint.get(name)
            # Treat &GT; like &gt;.
            # This is wrong for &Gt; and &Lt; which HTML5 adopted from MathML.
            # If htmlentitydefs included mappings for those entities,
            # then this code will magically work.
            or htmlentitydefs.name2codepoint.get(name.lower()))
        if decoding is not None: return unichr(decoding)
    return match.group(0)  # Treat "&noSuchEntity;" as "&noSuchEntity;"
...